From 75663a4902fa8ceb7b3a1bb0f8f68050132a05fc Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Thu, 9 Jun 2011 08:21:44 +0000 Subject: [PATCH] This is a big commit : do not hesitate to shout if a file is missing ;-) The delquad algo is now much more stable and nice Two 3D meshers have been added. One is an embryo of the 3D delhex mesh which is an extension of delquad. The other one is MMG, the mobile mesh generator of CECILE DOBRZYNSKI (Bordeaux I) and PASCAL FREY (PARIS VI). We are very happy that this new anisotropic 3D mesher is now available as an open source !! --- CMakeLists.txt | 7 + Common/CommandLine.cpp | 8 +- Common/DefaultOptions.h | 2 +- Common/GmshConfig.h.in | 1 + Common/GmshDefines.h | 3 + Common/Options.cpp | 9 + Fltk/optionWindow.cpp | 6 + Geo/GEdge.cpp | 11 + Geo/GFaceCompound.cpp | 7 +- Geo/Geo.cpp | 2 +- Mesh/BackgroundMesh.cpp | 21 +- Mesh/CMakeLists.txt | 2 +- Mesh/Field.cpp | 4 +- Mesh/meshGFace.cpp | 4 +- Mesh/meshGFaceDelaunayInsertion.cpp | 343 +- Mesh/meshGFaceDelaunayInsertion.h | 2 +- Mesh/meshGRegion.cpp | 12 +- Mesh/meshGRegionDelaunayInsertion.cpp | 419 +- Mesh/meshGRegionDelaunayInsertion.h | 2 + Mesh/meshGRegionMMG3D.cpp | 153 + Mesh/meshGRegionMMG3D.h | 5 + benchmarks/3d/coin.geo | 3 +- benchmarks/3d/thai.geo | 3 + benchmarks/step/capot.geo | 9 +- benchmarks/stl/mobilette.geo | 5 +- contrib/mmg3d/CMakeLists.txt | 69 + contrib/mmg3d/INSTALL.txt | 40 + contrib/mmg3d/LICENCE.txt | 621 + contrib/mmg3d/README.txt | 8 + contrib/mmg3d/build/CMakeLists.txt | 98 + contrib/mmg3d/build/libexamples/main.c | 129 + contrib/mmg3d/build/sources/analar.c | 357 + contrib/mmg3d/build/sources/analarcutting.c | 319 + contrib/mmg3d/build/sources/baryct.c | 112 + contrib/mmg3d/build/sources/boulep.c | 206 + contrib/mmg3d/build/sources/bucket.c | 385 + contrib/mmg3d/build/sources/cendel.c | 222 + contrib/mmg3d/build/sources/cenrad.c | 182 + contrib/mmg3d/build/sources/chkmsh.c | 182 + contrib/mmg3d/build/sources/chrono.c | 142 + contrib/mmg3d/build/sources/chrono.h | 77 + contrib/mmg3d/build/sources/colpoi.c | 523 + contrib/mmg3d/build/sources/coquil.c | 106 + contrib/mmg3d/build/sources/cutelt.c | 544 + contrib/mmg3d/build/sources/defines.h | 97 + contrib/mmg3d/build/sources/delaunay.c | 813 + contrib/mmg3d/build/sources/eigenv.c | 666 + contrib/mmg3d/build/sources/eigenv.h | 47 + contrib/mmg3d/build/sources/hash.c | 551 + contrib/mmg3d/build/sources/heap.c | 227 + contrib/mmg3d/build/sources/inout.c | 1417 ++ contrib/mmg3d/build/sources/length.c | 235 + contrib/mmg3d/build/sources/libmmg3d.h | 128 + .../mmg3d/build/sources/libmmg3d_internal.h | 59 + contrib/mmg3d/build/sources/librnbg.c | 461 + contrib/mmg3d/build/sources/librnbg.h | 68 + contrib/mmg3d/build/sources/locate.c | 141 + contrib/mmg3d/build/sources/matrix.c | 96 + contrib/mmg3d/build/sources/memory.c | 284 + contrib/mmg3d/build/sources/memory.h | 67 + contrib/mmg3d/build/sources/mesh.h | 411 + contrib/mmg3d/build/sources/mmg3d.c | 701 + contrib/mmg3d/build/sources/mmg3d1.c | 192 + contrib/mmg3d/build/sources/mmg3d4.c | 237 + contrib/mmg3d/build/sources/mmg3d9.c | 528 + contrib/mmg3d/build/sources/mmg3dConfig.h | 50 + contrib/mmg3d/build/sources/mmg3dlib.c | 494 + contrib/mmg3d/build/sources/movevertex.c | 366 + contrib/mmg3d/build/sources/optbdry.c | 272 + contrib/mmg3d/build/sources/optcoq.c | 120 + contrib/mmg3d/build/sources/optcte.c | 275 + contrib/mmg3d/build/sources/optlap.c | 284 + contrib/mmg3d/build/sources/optlen.c | 610 + contrib/mmg3d/build/sources/optlentet.c | 349 + contrib/mmg3d/build/sources/optra4.c | 106 + contrib/mmg3d/build/sources/opttet.c | 133 + contrib/mmg3d/build/sources/opttyp.c | 821 + contrib/mmg3d/build/sources/outqua.c | 318 + contrib/mmg3d/build/sources/pattern.c | 2440 ++ contrib/mmg3d/build/sources/quality.c | 1745 ++ contrib/mmg3d/build/sources/queue.c | 167 + contrib/mmg3d/build/sources/ratio.c | 435 + contrib/mmg3d/build/sources/scalem.c | 230 + contrib/mmg3d/build/sources/simu23.c | 144 + contrib/mmg3d/build/sources/simu44.c | 140 + contrib/mmg3d/build/sources/simu56.c | 364 + contrib/mmg3d/build/sources/simu68.c | 1130 + contrib/mmg3d/build/sources/simu710.c | 4021 ++++ contrib/mmg3d/build/sources/solmap.c | 208 + contrib/mmg3d/build/sources/spledg.c | 132 + contrib/mmg3d/build/sources/sproto.h | 240 + contrib/mmg3d/build/sources/swap23.c | 678 + contrib/mmg3d/build/sources/swap44.c | 608 + contrib/mmg3d/build/sources/swap56.c | 1956 ++ contrib/mmg3d/build/sources/swap68.c | 5674 +++++ contrib/mmg3d/build/sources/swap710.c | 19044 ++++++++++++++++ contrib/mmg3d/build/sources/swapar.c | 106 + contrib/mmg3d/build/sources/swaptet.c | 105 + contrib/mmg3d/build/sources/typelt.c | 378 + contrib/mmg3d/build/sources/zaldy.c | 256 + contrib/mpeg_encode/bframe.cpp | 2 +- contrib/mpeg_encode/bitio.cpp | 1 + contrib/mpeg_encode/block.cpp | 1 + contrib/mpeg_encode/iframe.cpp | 2 +- contrib/mpeg_encode/pframe.cpp | 2 +- 105 files changed, 56927 insertions(+), 271 deletions(-) create mode 100644 Mesh/meshGRegionMMG3D.cpp create mode 100644 Mesh/meshGRegionMMG3D.h create mode 100644 contrib/mmg3d/CMakeLists.txt create mode 100644 contrib/mmg3d/INSTALL.txt create mode 100644 contrib/mmg3d/LICENCE.txt create mode 100644 contrib/mmg3d/README.txt create mode 100644 contrib/mmg3d/build/CMakeLists.txt create mode 100644 contrib/mmg3d/build/libexamples/main.c create mode 100644 contrib/mmg3d/build/sources/analar.c create mode 100644 contrib/mmg3d/build/sources/analarcutting.c create mode 100644 contrib/mmg3d/build/sources/baryct.c create mode 100644 contrib/mmg3d/build/sources/boulep.c create mode 100644 contrib/mmg3d/build/sources/bucket.c create mode 100644 contrib/mmg3d/build/sources/cendel.c create mode 100644 contrib/mmg3d/build/sources/cenrad.c create mode 100644 contrib/mmg3d/build/sources/chkmsh.c create mode 100644 contrib/mmg3d/build/sources/chrono.c create mode 100644 contrib/mmg3d/build/sources/chrono.h create mode 100644 contrib/mmg3d/build/sources/colpoi.c create mode 100644 contrib/mmg3d/build/sources/coquil.c create mode 100644 contrib/mmg3d/build/sources/cutelt.c create mode 100644 contrib/mmg3d/build/sources/defines.h create mode 100644 contrib/mmg3d/build/sources/delaunay.c create mode 100644 contrib/mmg3d/build/sources/eigenv.c create mode 100644 contrib/mmg3d/build/sources/eigenv.h create mode 100644 contrib/mmg3d/build/sources/hash.c create mode 100644 contrib/mmg3d/build/sources/heap.c create mode 100644 contrib/mmg3d/build/sources/inout.c create mode 100644 contrib/mmg3d/build/sources/length.c create mode 100644 contrib/mmg3d/build/sources/libmmg3d.h create mode 100644 contrib/mmg3d/build/sources/libmmg3d_internal.h create mode 100644 contrib/mmg3d/build/sources/librnbg.c create mode 100644 contrib/mmg3d/build/sources/librnbg.h create mode 100644 contrib/mmg3d/build/sources/locate.c create mode 100644 contrib/mmg3d/build/sources/matrix.c create mode 100644 contrib/mmg3d/build/sources/memory.c create mode 100644 contrib/mmg3d/build/sources/memory.h create mode 100644 contrib/mmg3d/build/sources/mesh.h create mode 100644 contrib/mmg3d/build/sources/mmg3d.c create mode 100644 contrib/mmg3d/build/sources/mmg3d1.c create mode 100644 contrib/mmg3d/build/sources/mmg3d4.c create mode 100644 contrib/mmg3d/build/sources/mmg3d9.c create mode 100644 contrib/mmg3d/build/sources/mmg3dConfig.h create mode 100644 contrib/mmg3d/build/sources/mmg3dlib.c create mode 100644 contrib/mmg3d/build/sources/movevertex.c create mode 100644 contrib/mmg3d/build/sources/optbdry.c create mode 100644 contrib/mmg3d/build/sources/optcoq.c create mode 100644 contrib/mmg3d/build/sources/optcte.c create mode 100644 contrib/mmg3d/build/sources/optlap.c create mode 100644 contrib/mmg3d/build/sources/optlen.c create mode 100644 contrib/mmg3d/build/sources/optlentet.c create mode 100644 contrib/mmg3d/build/sources/optra4.c create mode 100644 contrib/mmg3d/build/sources/opttet.c create mode 100644 contrib/mmg3d/build/sources/opttyp.c create mode 100644 contrib/mmg3d/build/sources/outqua.c create mode 100644 contrib/mmg3d/build/sources/pattern.c create mode 100644 contrib/mmg3d/build/sources/quality.c create mode 100644 contrib/mmg3d/build/sources/queue.c create mode 100644 contrib/mmg3d/build/sources/ratio.c create mode 100644 contrib/mmg3d/build/sources/scalem.c create mode 100644 contrib/mmg3d/build/sources/simu23.c create mode 100644 contrib/mmg3d/build/sources/simu44.c create mode 100644 contrib/mmg3d/build/sources/simu56.c create mode 100644 contrib/mmg3d/build/sources/simu68.c create mode 100644 contrib/mmg3d/build/sources/simu710.c create mode 100644 contrib/mmg3d/build/sources/solmap.c create mode 100644 contrib/mmg3d/build/sources/spledg.c create mode 100644 contrib/mmg3d/build/sources/sproto.h create mode 100644 contrib/mmg3d/build/sources/swap23.c create mode 100644 contrib/mmg3d/build/sources/swap44.c create mode 100644 contrib/mmg3d/build/sources/swap56.c create mode 100644 contrib/mmg3d/build/sources/swap68.c create mode 100644 contrib/mmg3d/build/sources/swap710.c create mode 100644 contrib/mmg3d/build/sources/swapar.c create mode 100644 contrib/mmg3d/build/sources/swaptet.c create mode 100644 contrib/mmg3d/build/sources/typelt.c create mode 100644 contrib/mmg3d/build/sources/zaldy.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 744fe3695d..78caf910c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ option(ENABLE_MATHEX "Enable MathEx expression parser" ON) option(ENABLE_MED "Enable MED mesh and post-processing file formats" ON) option(ENABLE_MESH "Build the mesh module" ON) option(ENABLE_METIS "Enable Metis mesh partitioner" ON) +option(ENABLE_MMG3D "Enable 3D Mobile Mesh Generation" ON) option(ENABLE_MPEG_ENCODE "Enable built-in MPEG encoder" ON) option(ENABLE_MPI "Enable MPI parallelization" OFF) option(ENABLE_MSVC_STATIC_RUNTIME "Use static Visual C++ runtime" OFF) @@ -537,6 +538,12 @@ if(HAVE_MESH) set_config_option(HAVE_BAMG "Bamg") endif(ENABLE_BAMG) + if(ENABLE_MMG3D) + add_subdirectory(contrib/mmg3d) + include_directories(contrib/mmg3d/build/sources) + set_config_option(HAVE_MMG3D "Mmg3d") + endif(ENABLE_MMG3D) + if(ENABLE_TETGEN_NEW AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/TetgenNew/tetgen.h) add_subdirectory(contrib/TetgenNew) include_directories(contrib/TetgenNew) diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp index 12b07737ea..091f202422 100644 --- a/Common/CommandLine.cpp +++ b/Common/CommandLine.cpp @@ -66,7 +66,7 @@ void PrintUsage(const char *name) Msg::Direct(" -bin Use binary format when available"); Msg::Direct(" -parametric Save vertices with their parametric coordinates"); Msg::Direct(" -numsubedges Set the number of subdivisions when displaying high order elements"); - Msg::Direct(" -algo string Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d)"); + Msg::Direct(" -algo string Select mesh algorithm (meshadapt, del2d, front2d, delquad, del3d, front3d, mmg3d)"); Msg::Direct(" -smooth int Set number of mesh smoothing steps"); Msg::Direct(" -order int Set mesh order (1, ..., 5)"); Msg::Direct(" -optimize[_netgen] Optimize quality of tetrahedral elements"); @@ -550,6 +550,12 @@ void GetOptions(int argc, char *argv[]) CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; else if(!strncmp(argv[i], "front3d", 7) || !strncmp(argv[i], "netgen", 6)) CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL; + else if(!strncmp(argv[i], "mmg3d", 5)) + CTX::instance()->mesh.algo3d = ALGO_3D_MMG3D; + else if(!strncmp(argv[i], "delfr3d", 7)) + CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_DEL; + else if(!strncmp(argv[i], "delhex3d", 8)) + CTX::instance()->mesh.algo3d = ALGO_3D_FRONTAL_HEX; else Msg::Fatal("Unknown mesh algorithm"); i++; diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index d1d4947561..6d68032505 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -1018,7 +1018,7 @@ StringXNumber MeshOptions_Number[] = { #else ALGO_3D_FRONTAL , #endif - "3D mesh algorithm (1=Delaunay, 4=Frontal)" }, + "3D mesh algorithm (1=Delaunay, 4=Frontal, 5=Frontal Delaunay, 6=Frontal Hex, 7=MMG3D)" }, { F|O, "AngleSmoothNormals" , opt_mesh_angle_smooth_normals , 30.0 , "Threshold angle below which normals are not smoothed" }, { F|O, "AnisoMax" , opt_mesh_aniso_max, 1.e33, diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in index 0b6e218679..8997d6166b 100644 --- a/Common/GmshConfig.h.in +++ b/Common/GmshConfig.h.in @@ -31,6 +31,7 @@ #cmakedefine HAVE_MED #cmakedefine HAVE_MESH #cmakedefine HAVE_METIS +#cmakedefine HAVE_MMG3D #cmakedefine HAVE_MPEG_ENCODE #cmakedefine HAVE_MPI #cmakedefine HAVE_NATIVE_FILE_CHOOSER diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h index c9588df974..40883c08ef 100644 --- a/Common/GmshDefines.h +++ b/Common/GmshDefines.h @@ -188,6 +188,9 @@ // 3D meshing algorithms (numbers should not be changed) #define ALGO_3D_DELAUNAY 1 #define ALGO_3D_FRONTAL 4 +#define ALGO_3D_FRONTAL_DEL 5 +#define ALGO_3D_FRONTAL_HEX 6 +#define ALGO_3D_MMG3D 7 // Meshing methods #define MESH_NONE 0 diff --git a/Common/Options.cpp b/Common/Options.cpp index ea727f097b..fad1ca4b32 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -5788,6 +5788,15 @@ double opt_mesh_algo3d(OPT_ARGS_NUM) #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) { switch (CTX::instance()->mesh.algo3d) { + case ALGO_3D_MMG3D: + FlGui::instance()->options->mesh.choice[3]->value(4); + break; + case ALGO_3D_FRONTAL_HEX: + FlGui::instance()->options->mesh.choice[3]->value(3); + break; + case ALGO_3D_FRONTAL_DEL: + FlGui::instance()->options->mesh.choice[3]->value(2); + break; case ALGO_3D_FRONTAL: FlGui::instance()->options->mesh.choice[3]->value(1); break; diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index 658e241b5b..ae18612bb1 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -482,6 +482,9 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data) ALGO_2D_AUTO); opt_mesh_algo3d(0, GMSH_SET, (o->mesh.choice[3]->value() == 0) ? ALGO_3D_DELAUNAY : + (o->mesh.choice[3]->value() == 2) ? ALGO_3D_FRONTAL_DEL : + (o->mesh.choice[3]->value() == 3) ? ALGO_3D_FRONTAL_HEX : + (o->mesh.choice[3]->value() == 4) ? ALGO_3D_MMG3D : ALGO_3D_FRONTAL); opt_mesh_algo_recombine(0, GMSH_SET, o->mesh.choice[1]->value()); opt_mesh_recombine_all(0, GMSH_SET, o->mesh.butt[21]->value()); @@ -2068,6 +2071,9 @@ optionWindow::optionWindow(int deltaFontSize) static Fl_Menu_Item menu_3d_algo[] = { {"Delaunay", 0, 0, 0}, {"Frontal", 0, 0, 0}, + {"Frontal Delaunay", 0, 0, 0}, + {"Frontal Hex", 0, 0, 0}, + {"MMG3D", 0, 0, 0}, {0} }; static Fl_Menu_Item menu_recombination_algo[] = { diff --git a/Geo/GEdge.cpp b/Geo/GEdge.cpp index 7e0a86b73b..4c4606cafc 100644 --- a/Geo/GEdge.cpp +++ b/Geo/GEdge.cpp @@ -219,6 +219,17 @@ SVector3 GEdge::secondDer(double par) const { // use central differences const double eps = 1.e-3; + Range<double> rg = parBounds(0); + if (par-eps <= rg.low()){ + SVector3 x1 = firstDer(par); + SVector3 x2 = firstDer(par + eps); + return 1000 * (x2 - x1); + } + else if (par+eps >= rg.high()){ + SVector3 x1 = firstDer(par-eps); + SVector3 x2 = firstDer(par); + return 1000 * (x2 - x1); + } SVector3 x1 = firstDer(par - eps); SVector3 x2 = firstDer(par + eps); return 500 * (x2 - x1); diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp index 2b03cb029f..c8a0e16942 100644 --- a/Geo/GFaceCompound.cpp +++ b/Geo/GFaceCompound.cpp @@ -1697,13 +1697,18 @@ GPoint GFaceCompound::point(double par1, double par2) const } const bool LINEARMESH = true; //false + + if (lt->gf->geomType() != GEntity::DiscreteSurface){ + SPoint2 pParam = lt->gfp1*(1.-U-V) + lt->gfp2*U + lt->gfp3*V; + return lt->gf->point(pParam); + } if(LINEARMESH){ //linear Lagrange mesh //------------------------- p = lt->v1*(1.-U-V) + lt->v2*U + lt->v3*V; - return GPoint(p.x(),p.y(),p.z(),this,par); + return GPoint(p.x(),p.y(),p.z(),this,par); } else{ diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp index 3e5aab3dcc..776a25aa76 100644 --- a/Geo/Geo.cpp +++ b/Geo/Geo.cpp @@ -3543,7 +3543,7 @@ void setSurfaceEmbeddedCurves(Surface *s, List_T *curves) if(c) List_Add(s->EmbeddedCurves, &c); else - Msg::Error("Unknown curve %d", iCurve); + Msg::Error("Unknown curve %d", (int)iCurve); } } diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index 369d107f27..b81af0c6e9 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -222,16 +222,16 @@ static double LC_MVertex_CURV(GEntity *ge, double U, double V) double Crv = 0; switch(ge->dim()){ case 0: - Crv = max_edge_curvature((const GVertex *)ge); - Crv = std::max(max_surf_curvature((const GVertex *)ge), Crv); - //Crv = max_surf_curvature((const GVertex *)ge); + // Crv = max_edge_curvature((const GVertex *)ge); + // Crv = std::max(max_surf_curvature((const GVertex *)ge), Crv); + Crv = max_surf_curvature((const GVertex *)ge); break; case 1: { GEdge *ged = (GEdge *)ge; - Crv = ged->curvature(U)*2; - Crv = std::max(Crv, max_surf_curvature(ged, U)); - //Crv = max_surf_curvature(ged, U); + // Crv = ged->curvature(U)*2; + // Crv = std::max(Crv, max_surf_curvature(ged, U)); + Crv = max_surf_curvature(ged, U); } break; case 2: @@ -441,16 +441,17 @@ backgroundMesh::backgroundMesh(GFace *_gf) _octree = new MElementOctree(_triangles); // compute the mesh sizes at nodes - if (CTX::instance()->mesh.lcFromPoints) + if (CTX::instance()->mesh.lcExtendFromBoundary){ propagate1dMesh(_gf); + } else { std::map<MVertex*, MVertex*>::iterator itv2 = _2Dto3D.begin(); for ( ; itv2 != _2Dto3D.end(); ++itv2){ _sizes[itv2->first] = MAX_LC; } } - // ensure that other criteria are fullfilled - updateSizes(_gf); + // ensure that other criteria are fullfilled + // updateSizes(_gf); // compute optimal mesh orientations propagatecrossField(_gf); @@ -700,7 +701,7 @@ void backgroundMesh::updateSizes(GFace *_gf) bool success = reparamMeshVertexOnFace(v, _gf, p); lc = BGM_MeshSize(_gf, p.x(), p.y(), v->x(), v->y(), v->z()); } - // printf("2D -- %g %g 3D -- %g %g\n",p.x(),p.y(),v->x(),v->y()); + // printf("2D -- %g %g 3D -- %g %g lc %g\n",p.x(),p.y(),v->x(),v->y(),lc); itv->second = std::min(lc,itv->second); itv->second = std::max(itv->second, CTX::instance()->mesh.lcMin); itv->second = std::min(itv->second, CTX::instance()->mesh.lcMax); diff --git a/Mesh/CMakeLists.txt b/Mesh/CMakeLists.txt index 22aeb98b05..3f626aff6c 100644 --- a/Mesh/CMakeLists.txt +++ b/Mesh/CMakeLists.txt @@ -16,7 +16,7 @@ set(SRC meshGRegion.cpp meshGRegionDelaunayInsertion.cpp meshGRegionTransfinite.cpp meshGRegionExtruded.cpp meshGRegionCarveHole.cpp - meshGRegionLocalMeshMod.cpp + meshGRegionLocalMeshMod.cpp meshGRegionMMG3D.cpp BackgroundMesh.cpp qualityMeasures.cpp BoundaryLayers.cpp diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp index de40cee7b4..b26a705e09 100644 --- a/Mesh/Field.cpp +++ b/Mesh/Field.cpp @@ -1580,7 +1580,8 @@ class AttractorField : public Field for(std::list<int>::iterator it = edges_id.begin(); it != edges_id.end(); ++it) { Curve *c = FindCurve(*it); - if(c) { + GEdge *e = GModel::current()->getEdgeByTag(*it); + if(c && !e) { for(int i = 0; i < n_nodes_by_edge; i++) { double u = (double)i / (n_nodes_by_edge - 1); Vertex V = InterpolateCurve(c, u, 0); @@ -1589,7 +1590,6 @@ class AttractorField : public Field } } else { - GEdge *e = GModel::current()->getEdgeByTag(*it); if(e) { for(int i = 0; i < n_nodes_by_edge; i++) { double u = (double)i / (n_nodes_by_edge - 1); diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 609a15a4e7..4da46d9e24 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -886,7 +886,7 @@ static bool meshGenerator(GFace *gf, int RECUR_ITER, if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) bowyerWatsonFrontal(gf); else if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL_QUAD) - bowyerWatsonFrontalQuad(gf); + bowyerWatsonFrontalLayers(gf,true); else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || CTX::instance()->mesh.algo2d == ALGO_2D_AUTO) bowyerWatson(gf); @@ -1477,7 +1477,7 @@ static bool meshGeneratorPeriodic(GFace *gf, bool debug = true) if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) bowyerWatsonFrontal(gf); else if(CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL_QUAD) - bowyerWatsonFrontalQuad(gf); + bowyerWatsonFrontalLayers(gf,true); else if(CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || CTX::instance()->mesh.algo2d == ALGO_2D_AUTO) bowyerWatson(gf); diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index f5eb885cf2..d70a5ca0ab 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -15,6 +15,7 @@ #include "GFace.h" #include "Numeric.h" #include "STensor3.h" +#include "Context.h" double LIMIT_ = 0.5 * sqrt(2.0) * 1; @@ -558,7 +559,9 @@ bool insertVertex(GFace *gf, MVertex *v, double *param , MTri3 *t, double d2 = sqrt((it->v[1]->x() - v->x()) * (it->v[1]->x() - v->x()) + (it->v[1]->y() - v->y()) * (it->v[1]->y() - v->y()) + (it->v[1]->z() - v->z()) * (it->v[1]->z() - v->z())); - if (d1 < LL * .25 || d2 < LL * .25) onePointIsTooClose = true; + const double MID[3] = {0.5*(it->v[0]->x()+it->v[1]->x()),0.5*(it->v[0]->y()+it->v[1]->y()),0.5*(it->v[0]->z()+it->v[1]->z())}; + double d3 = sqrt((MID[0] - v->x()) * (MID[0] - v->x()) + (MID[1] - v->y()) * (MID[1] - v->y()) + (MID[2] - v->z()) * (MID[2] - v->z())); + if (d1 < LL * .25 || d2 < LL * .25 || d3 < LL * .25) onePointIsTooClose = true; // if (t4->getRadius () < LIMIT_ / 2) onePointIsTooClose = true; @@ -662,6 +665,7 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2], bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8); if (inside) return t; SPoint3 q1(pt[0],pt[1],0); + int ITER = 0; while (1){ // printf("%d %d %d\n",t->tri()->getVertex(0)->getIndex(),t->tri()->getVertex(1)->getIndex() ,t->tri()->getVertex(2)->getIndex()); SPoint3 q2((Us[t->tri()->getVertex(0)->getIndex()] + Us[t->tri()->getVertex(1)->getIndex()] + Us[t->tri()->getVertex(2)->getIndex()])/3.0, @@ -679,6 +683,7 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2], if (!t)break; bool inside = invMapUV(t->tri(), pt, Us, Vs, uv, 1.e-8); if (inside) {return t;} + if (ITER++ > AllTris.size())break; } for(std::set<MTri3*,compareTri3Ptr>::iterator itx = AllTris.begin(); itx != AllTris.end();++itx){ @@ -730,7 +735,7 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it if (inside)ptin = worst->getNeigh(2); } } - else if (MTri3::radiusNorm == -1){ + else { ptin = search4Triangle (worst, center, Us, Vs, AllTris); if (ptin)inside = true; } @@ -745,7 +750,7 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it MVertex *v = new MFaceVertex(p.x(), p.y(), p.z(), gf, center[0], center[1]); v->setIndex(Us.size()); double lc1,lc; - if (0 && backgroundMesh::current()){ + if (backgroundMesh::current()){ lc1 = lc = backgroundMesh::current()->operator()(center[0], center[1], 0.0); } @@ -947,6 +952,69 @@ static double lengthMetric(const double p[2], const double q[2], */ +void optimalPointFrontal (GFace *gf, + MTri3* worst, + int active_edge, + std::vector<double> &Us, + std::vector<double> &Vs, + std::vector<double> &vSizes, + std::vector<double> &vSizesBGM, + double newPoint[2], + double metric[3]){ + double center[2],r2; + MTriangle *base = worst->tri(); + circUV(base, Us, Vs, center, gf); + double pa[2] = {(Us[base->getVertex(0)->getIndex()] + + Us[base->getVertex(1)->getIndex()] + + Us[base->getVertex(2)->getIndex()]) / 3., + (Vs[base->getVertex(0)->getIndex()] + + Vs[base->getVertex(1)->getIndex()] + + Vs[base->getVertex(2)->getIndex()]) / 3.}; + buildMetric(gf, pa, metric); + circumCenterMetric(worst->tri(), metric, Us, Vs, center, r2); + // compute the middle point of the edge + int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1; + int ip2 = active_edge; + + double P[2] = {Us[base->getVertex(ip1)->getIndex()], + Vs[base->getVertex(ip1)->getIndex()]}; + double Q[2] = {Us[base->getVertex(ip2)->getIndex()], + Vs[base->getVertex(ip2)->getIndex()]}; + double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])}; + + // now we have the edge center and the center of the circumcircle, + // we try to find a point that would produce a perfect triangle while + // connecting the 2 points of the active edge + + double dir[2] = {center[0] - midpoint[0], center[1] - midpoint[1]}; + double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]); + dir[0] /= norm; + dir[1] /= norm; + const double RATIO = sqrt(dir[0] * dir[0] * metric[0] + + 2 * dir[1] * dir[0] * metric[1] + + dir[1] * dir[1] * metric[2]); + + const double p = 0.5 * lengthMetric(P, Q, metric); // / RATIO; + const double q = lengthMetric(center, midpoint, metric); + const double rhoM1 = 0.5 * + (vSizes[base->getVertex(ip1)->getIndex()] + + vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; + const double rhoM2 = 0.5 * + (vSizesBGM[base->getVertex(ip1)->getIndex()] + + vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; + const double rhoM = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2; + + const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q)); + const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) / RATIO; + + // printf("(%g %g) (%g %g) %g %g %g %g %g %g\n",P[0],P[1],Q[0],Q[1],RATIO,p,q,rhoM,rhoM_hat,d); + + + newPoint[0] = midpoint[0] + d * dir[0]; + newPoint[1] = midpoint[1] + d * dir[1]; +} + + void bowyerWatsonFrontal(GFace *gf) { std::set<MTri3*,compareTri3Ptr> AllTris; @@ -975,9 +1043,9 @@ void bowyerWatsonFrontal(GFace *gf) /* if(ITER % 1== 0){ char name[245]; - sprintf(name,"delfr2d%d-ITER%4d.pos",gf->tag(),ITER); + sprintf(name,"delfr2d%d-ITER%d.pos",gf->tag(),ITER); _printTris (name, AllTris, Us,Vs,false); - sprintf(name,"delfr2dA%d-ITER%4d.pos",gf->tag(),ITER); + sprintf(name,"delfr2dA%d-ITER%d.pos",gf->tag(),ITER); _printTris (name, ActiveTris, Us,Vs,false); } */ @@ -991,64 +1059,13 @@ void bowyerWatsonFrontal(GFace *gf) if(ITER++ % 5000 == 0) Msg::Debug("%7d points created -- Worst tri radius is %8.3f", vSizes.size(), worst->getRadius()); - // compute circum center of that guy - double center[2],metric[3],r2; - MTriangle *base = worst->tri(); - circUV(base, Us, Vs, center, gf); - double pa[2] = {(Us[base->getVertex(0)->getIndex()] + - Us[base->getVertex(1)->getIndex()] + - Us[base->getVertex(2)->getIndex()]) / 3., - (Vs[base->getVertex(0)->getIndex()] + - Vs[base->getVertex(1)->getIndex()] + - Vs[base->getVertex(2)->getIndex()]) / 3.}; - buildMetric(gf, pa, metric); - circumCenterMetric(worst->tri(), metric, Us, Vs, center, r2); - // compute the middle point of the edge - int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1; - int ip2 = active_edge; - // printf("the active edge is %d : %g %g -> %g %g\n", - // active_edge,base->getVertex(ip1)->x(),base->getVertex(ip1)->y(), - // base->getVertex(ip2)->x(),base->getVertex(ip2)->y()); - double P[2] = {Us[base->getVertex(ip1)->getIndex()], - Vs[base->getVertex(ip1)->getIndex()]}; - double Q[2] = {Us[base->getVertex(ip2)->getIndex()], - Vs[base->getVertex(ip2)->getIndex()]}; - double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])}; - - // now we have the edge center and the center of the circumcircle, - // we try to find a point that would produce a perfect triangle while - // connecting the 2 points of the active edge - - double dir[2] = {center[0] - midpoint[0], center[1] - midpoint[1]}; - double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]); - dir[0] /= norm; - dir[1] /= norm; - const double RATIO = sqrt(dir[0] * dir[0] * metric[0] + - 2 * dir[1] * dir[0] * metric[1] + - dir[1] * dir[1] * metric[2]); - - const double p = 0.5 * lengthMetric(P, Q, metric); // / RATIO; - const double q = lengthMetric(center, midpoint, metric); - const double rhoM1 = 0.5 * - (vSizes[base->getVertex(ip1)->getIndex()] + - vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; - const double rhoM2 = 0.5 * - (vSizesBGM[base->getVertex(ip1)->getIndex()] + - vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; - const double rhoM = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2; - // const double rhoM = 0.5 * - // (vSizes[base->getVertex(ip1)->getIndex()] + - // vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; - - const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q)); - const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) / RATIO; - - double newPoint[2] = {midpoint[0] + d * dir[0], midpoint[1] + d * dir[1]}; + double newPoint[2], metric[3]; + optimalPointFrontal (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric); insertAPoint(gf, AllTris.end(), newPoint, metric, Us, Vs, vSizes, vSizesBGM, vMetricsBGM, AllTris, &ActiveTris, worst); } - /* - if(ITER % 100== 0){ + + /* if(ITER % 1== 0){ char name[245]; sprintf(name,"frontal%d-ITER%d.pos",gf->tag(),ITER); _printTris (name, AllTris, Us,Vs,false); @@ -1064,8 +1081,91 @@ void bowyerWatsonFrontal(GFace *gf) transferDataStructure(gf, AllTris, Us, Vs); } +void optimalPointFrontalQuad (GFace *gf, + MTri3* worst, + int active_edge, + std::vector<double> &Us, + std::vector<double> &Vs, + std::vector<double> &vSizes, + std::vector<double> &vSizesBGM, + double newPoint[2], + double metric[3]){ + MTriangle *base = worst->tri(); + int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1; + int ip2 = active_edge; + int ip3 = (active_edge+1)%3; + + double P[2] = {Us[base->getVertex(ip1)->getIndex()], + Vs[base->getVertex(ip1)->getIndex()]}; + double Q[2] = {Us[base->getVertex(ip2)->getIndex()], + Vs[base->getVertex(ip2)->getIndex()]}; + double O[2] = {Us[base->getVertex(ip3)->getIndex()], + Vs[base->getVertex(ip3)->getIndex()]}; + double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])}; + + // compute background mesh data + double quadAngle = backgroundMesh::current()->getAngle (midpoint[0],midpoint[1],0); + double center[2]; + circumCenterInfinite (base, quadAngle,Us,Vs,center); + + // rotate the points with respect to the angle + double XP1 = 0.5*(Q[0] - P[0]); + double YP1 = 0.5*(Q[1] - P[1]); + double xp = XP1 * cos(quadAngle) + YP1 * sin(quadAngle); + double yp = -XP1 * sin(quadAngle) + YP1 * cos(quadAngle); + // ensure xp > yp + bool exchange = false; + if (fabs(xp) < fabs(yp)){ + double temp = xp; + xp = yp; + yp = temp; + exchange = true; + } + + buildMetric(gf, midpoint, metric); + double RATIO = 1./pow(metric[0]*metric[2]-metric[1]*metric[1],0.25); + + const double p = 0.5 * lengthInfniteNorm(P, Q, quadAngle); + const double q = lengthInfniteNorm(center, midpoint, quadAngle); + const double rhoM1 = 0.5 * RATIO * + (vSizes[base->getVertex(ip1)->getIndex()] + + vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; + const double rhoM2 = 0.5 * RATIO * + (vSizesBGM[base->getVertex(ip1)->getIndex()] + + vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; + const double rhoM = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2; + + const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q)); + const double factor = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) /(sqrt(3)*p); + + double npx,npy; + if (xp*yp > 0){ + npx = - fabs(xp)*factor; + npy = fabs(xp)*(1.+factor) - fabs(yp); + } + else { + npx = fabs(xp) * factor; + npy = (1.+factor)*fabs(xp) - fabs(yp); + } + if (exchange){ + double temp = npx; + npx = npy; + npy = temp; + } + + + newPoint[0] = midpoint[0] + cos(quadAngle) * npx - sin(quadAngle) * npy; + newPoint[1] = midpoint[1] + sin(quadAngle) * npx + cos(quadAngle) * npy; + + if ((midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) + + (midpoint[1] - newPoint[1])*(midpoint[1] - O[1]) < 0){ + newPoint[0] = midpoint[0] - cos(quadAngle) * npx + sin(quadAngle) * npy; + newPoint[1] = midpoint[1] - sin(quadAngle) * npx - cos(quadAngle) * npy; + } +} -void bowyerWatsonFrontalQuad(GFace *gf) + +void bowyerWatsonFrontalLayers(GFace *gf, bool quad) { std::set<MTri3*,compareTri3Ptr> AllTris; @@ -1080,7 +1180,10 @@ void bowyerWatsonFrontalQuad(GFace *gf) gf->triangles[i]->getVertex(1), gf->triangles[i]->getVertex(2))); } + int CurvControl = CTX::instance()->mesh.lcFromCurvature; + CTX::instance()->mesh.lcFromCurvature = 0; bowyerWatson(gf); + CTX::instance()->mesh.lcFromCurvature = CurvControl; backgroundMesh::set(gf); char name[256]; sprintf(name,"bgm-%d.pos",gf->tag()); @@ -1091,10 +1194,10 @@ void bowyerWatsonFrontalQuad(GFace *gf) gf->triangles = TR; } - LIMIT_ = sqrt(2)*.99; - // LIMIT_ = 1.7; - MTri3::radiusNorm = -1; - + if (quad){ + LIMIT_ = sqrt(2)*.99; + MTri3::radiusNorm =-1; + } buildMeshGenerationDataStructures (gf, AllTris, vSizes, vSizesBGM, vMetricsBGM,Us, Vs); @@ -1117,6 +1220,7 @@ void bowyerWatsonFrontalQuad(GFace *gf) // insert points int ITERATION = 1; + int max_layers = quad ? 10000 : 4; while (1){ ITERATION ++; if(ITERATION % 1== 0){ @@ -1142,7 +1246,7 @@ void bowyerWatsonFrontalQuad(GFace *gf) MTri3 *worst = (*WORST_ITER); ActiveTris.erase(WORST_ITER); - if (!worst->isDeleted() && isActive(worst, LIMIT_, active_edge,&_front) && + if (!worst->isDeleted() && (ITERATION > max_layers ? isActive(worst, LIMIT_, active_edge) : isActive(worst, LIMIT_, active_edge,&_front) ) && worst->getRadius() > LIMIT_){ // for (active_edge = 0 ; active_edge < 0 ; active_edge ++){ // if (active_edges[active_edge])break; @@ -1152,107 +1256,9 @@ void bowyerWatsonFrontalQuad(GFace *gf) vSizes.size(), worst->getRadius(),_front.size()); // compute the middle point of the edge - MTriangle *base = worst->tri(); - int ip1 = active_edge - 1 < 0 ? 2 : active_edge - 1; - int ip2 = active_edge; - int ip3 = (active_edge+1)%3; - - double P[2] = {Us[base->getVertex(ip1)->getIndex()], - Vs[base->getVertex(ip1)->getIndex()]}; - double Q[2] = {Us[base->getVertex(ip2)->getIndex()], - Vs[base->getVertex(ip2)->getIndex()]}; - double O[2] = {Us[base->getVertex(ip3)->getIndex()], - Vs[base->getVertex(ip3)->getIndex()]}; - double midpoint[2] = {0.5 * (P[0] + Q[0]), 0.5 * (P[1] + Q[1])}; - - // compute background mesh data - double quadAngle = backgroundMesh::current()->getAngle (midpoint[0],midpoint[1],0); - // quadAngle = 35*M_PI/180; - //double quadAngle = backgroundMesh::current()->getAngle (0.5*(base->getVertex(ip1)->x()+base->getVertex(ip2)->x()), - // 0.5*(base->getVertex(ip1)->y()+base->getVertex(ip2)->y()), - // 0.5*(base->getVertex(ip1)->x()+base->getVertex(ip2)->x())); - // printf("quadAngle = %12.5E\n",quadAngle*180/M_PI); - // double meshSize = backgroundMesh::current()->operator()(midpoint[0],midpoint[1],0); - //double quadAngle = 0; - double center[2]; - circumCenterInfinite (base, quadAngle,Us,Vs,center); - - // rotate the points with respect to the angle - double XP1 = 0.5*(Q[0] - P[0]); - double YP1 = 0.5*(Q[1] - P[1]); - double xp = XP1 * cos(quadAngle) + YP1 * sin(quadAngle); - double yp = -XP1 * sin(quadAngle) + YP1 * cos(quadAngle); - // ensure xp > yp - bool exchange = false; - if (fabs(xp) < fabs(yp)){ - double temp = xp; - xp = yp; - yp = temp; - exchange = true; - } - - // dl^2 = dx^2 sqrt(\det M) - double metric[3]; - buildMetric(gf, midpoint, metric); - double RATIO = 1./pow(metric[0]*metric[2]-metric[1]*metric[1],0.25); - - if (gf->tag() == 1900){RATIO = 0.3;/*printf("%g ratio\n",RATIO);*/} - // printf("%g ratio\n",RATIO); - const double p = 0.5 * lengthInfniteNorm(P, Q, quadAngle); - const double q = lengthInfniteNorm(center, midpoint, quadAngle); - const double rhoM1 = 0.5 * RATIO * - (vSizes[base->getVertex(ip1)->getIndex()] + - vSizes[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; - const double rhoM2 = 0.5 * RATIO * - (vSizesBGM[base->getVertex(ip1)->getIndex()] + - vSizesBGM[base->getVertex(ip2)->getIndex()] ) / sqrt(3.);// * RATIO; - const double rhoM = Extend1dMeshIn2dSurfaces() ? std::min(rhoM1, rhoM2) : rhoM2; - - const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q)); - // const double rhoM_hat = std::max(rhoM, p); - // assume rhoM = L/\sqrt{3} - // assume that p = L/2 - // d = L/\sqrt{3} + \sqrt{L/3 - L/4} = L/\sqrt{3} + L/2\sqrt{3} = \sqrt{3} L / 2 ... OK - const double factor = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) /(sqrt(3)*p); - // printf("factor = %g\n",factor); - - double npx,npy; - if (xp*yp > 0){ - npx = - fabs(xp)*factor; - npy = fabs(xp)*(1.+factor) - fabs(yp); - } - else { - npx = fabs(xp) * factor; - npy = (1.+factor)*fabs(xp) - fabs(yp); - } - if (exchange){ - double temp = npx; - npx = npy; - npy = temp; - } - - - double newPoint[2] = {midpoint[0] + cos(quadAngle) * npx - sin(quadAngle) * npy, - midpoint[1] + sin(quadAngle) * npx + cos(quadAngle) * npy}; - /* - printf("exchange %d\n",exchange); - printf("P %g %g\n",P[0],P[1]); - printf("Q %g %g\n",Q[0],Q[1]); - printf("midpoint %g %g\n",midpoint[0],midpoint[1]); - printf("xp yp %g %g\n",xp,yp); - printf("O %g %g\n",O[0],O[1]); - printf("dx %g %g\n",npx,npy); - */ - if ((midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) + - (midpoint[1] - newPoint[1])*(midpoint[1] - O[1]) < 0){ - newPoint[0] = midpoint[0] - cos(quadAngle) * npx + sin(quadAngle) * npy; - newPoint[1] = midpoint[1] - sin(quadAngle) * npx - cos(quadAngle) * npy; - - // printf("wrong sense %g \n",(midpoint[0] - newPoint[0])*(midpoint[0] - O[0]) + - // (midpoint[1] - newPoint[1])*(midpoint[1] - O[1])); - } - - // printf("new %g %g\n",newPoint[0],newPoint[1]); + double newPoint[2],metric[3]={1,0,1}; + if (quad)optimalPointFrontalQuad (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric); + else optimalPointFrontal (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric); insertAPoint(gf, AllTris.end(), newPoint, 0, Us, Vs, vSizes, @@ -1261,8 +1267,9 @@ void bowyerWatsonFrontalQuad(GFace *gf) // ActiveTrisNotInFront.insert(worst); // } + /* - if(ITER % 100== 0){ + if(ITER % 1== 0){ char name[245]; sprintf(name,"frontal%d-ITER%d.pos",gf->tag(),ITER); _printTris (name, AllTris, Us,Vs,false); diff --git a/Mesh/meshGFaceDelaunayInsertion.h b/Mesh/meshGFaceDelaunayInsertion.h index 0aab515285..0890d9888c 100644 --- a/Mesh/meshGFaceDelaunayInsertion.h +++ b/Mesh/meshGFaceDelaunayInsertion.h @@ -96,7 +96,7 @@ void connectTriangles(std::vector<MTri3*> &); void connectTriangles(std::set<MTri3*,compareTri3Ptr> &AllTris); void bowyerWatson(GFace *gf); void bowyerWatsonFrontal(GFace *gf); -void bowyerWatsonFrontalQuad(GFace *gf); +void bowyerWatsonFrontalLayers(GFace *gf, bool quad); struct edgeXface { diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp index 0f104fa8f6..4fb32b0633 100644 --- a/Mesh/meshGRegion.cpp +++ b/Mesh/meshGRegion.cpp @@ -21,6 +21,7 @@ #include "BDS.h" #include "Context.h" #include "GFaceCompound.h" +#include "meshGRegionMMG3D.h" #if defined(HAVE_ANN) #include "ANN/ANN.h" @@ -561,7 +562,14 @@ void MeshDelaunayVolume(std::vector<GRegion*> ®ions) } // now do insertion of points - insertVerticesInRegion(gr); + if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL_DEL) + bowyerWatsonFrontalLayers(gr, false); + else if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL_HEX) + bowyerWatsonFrontalLayers(gr, true); + else if(CTX::instance()->mesh.algo3d == ALGO_3D_MMG3D) + refineMeshMMG(gr); + else + insertVerticesInRegion(gr); #endif } @@ -851,7 +859,7 @@ void meshGRegion::operator() (GRegion *gr) std::list<GFace*> myface = gr->faces(); - if(CTX::instance()->mesh.algo3d == ALGO_3D_DELAUNAY){ + if(CTX::instance()->mesh.algo3d != ALGO_3D_FRONTAL){ delaunay.push_back(gr); } else if(CTX::instance()->mesh.algo3d == ALGO_3D_FRONTAL){ diff --git a/Mesh/meshGRegionDelaunayInsertion.cpp b/Mesh/meshGRegionDelaunayInsertion.cpp index 484c31b5e3..9eb2efa6bd 100644 --- a/Mesh/meshGRegionDelaunayInsertion.cpp +++ b/Mesh/meshGRegionDelaunayInsertion.cpp @@ -17,6 +17,25 @@ #include "GRegion.h" #include "MTriangle.h" #include "Numeric.h" +#include "Context.h" + +int MTet4::radiusNorm = 2; +static double LIMIT_ = 1; + + +static bool isActive(MTet4 *t, double limit_, int &active) +{ + if (t->isDeleted()) return false; + for (active = 0; active < 4; active++){ + MTet4 *neigh = t->getNeigh(active); + if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) { + return true; + } + } + return false; +} + + int MTet4::inCircumSphere(const double *p) const { @@ -82,6 +101,35 @@ void connectTets(ITER beg, ITER end) } } +static void updateActiveFaces(MTet4 *t, double limit_, std::set<MFace,Less_Face> &front) +{ + if (t->isDeleted()) return; + for (int active = 0; active < 4; active++){ + MTet4 *neigh = t->getNeigh(active); + if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) { + faceXtet fxt (t,active); + MFace me (fxt.v[0],fxt.v[1],fxt.v[2]); + front.insert(me); + } + } +} + +static bool isActive(MTet4 *t, double limit_, int &i, std::set<MFace,Less_Face> *front) +{ + if (t->isDeleted()) return false; + for (i = 0; i < 4; i++){ + MTet4 *neigh = t->getNeigh(i); + if (!neigh || (neigh->getRadius() < limit_ && neigh->getRadius() > 0)) { + faceXtet fxt (t,i); + MFace me (fxt.v[0],fxt.v[1],fxt.v[2]); + if(front->find(me) != front->end()){ + return true; + } + } + } + return false; +} + void connectTets(std::list<MTet4*> &l) { connectTets(l.begin(), l.end()); } void connectTets(std::vector<MTet4*> &l) { connectTets(l.begin(), l.end()); } @@ -121,8 +169,9 @@ bool insertVertex(MVertex *v, MTet4 *t, MTet4Factory &myFactory, std::set<MTet4*,compareTet4Ptr> &allTets, - std::vector<double> & vSizes, - std::vector<double> & vSizesBGM) + std::vector<double> & vSizes, + std::vector<double> & vSizesBGM, + std::set<MTet4*,compareTet4Ptr> *activeTets = 0 ) { std::list<faceXtet> shell; std::list<MTet4*> cavity; @@ -130,102 +179,83 @@ bool insertVertex(MVertex *v, recurFindCavity(shell, cavity, v, t); - // Msg::Info("%d %d",cavity.size(),NC); - // if (NC != cavity.size())throw; - // check that volume is conserved double newVolume = 0; double oldVolume = 0; - // char name2[245]; - // FILE *ff2 = fopen (name2,"w"); - // fprintf(ff2,"View\"test\"{\n"); - std::list<MTet4*>::iterator ittet = cavity.begin(); std::list<MTet4*>::iterator ittete = cavity.end(); while (ittet != ittete){ oldVolume += fabs((*ittet)->getVolume()); -// fprintf(ff2,"SS(%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0,0};\n", -// (*ittet)->tet()->getVertex(0)->x(), -// (*ittet)->tet()->getVertex(0)->y(), -// (*ittet)->tet()->getVertex(0)->z(), -// (*ittet)->tet()->getVertex(1)->x(), -// (*ittet)->tet()->getVertex(1)->y(), -// (*ittet)->tet()->getVertex(1)->z(), -// (*ittet)->tet()->getVertex(2)->x(), -// (*ittet)->tet()->getVertex(2)->y(), -// (*ittet)->tet()->getVertex(2)->z(), -// (*ittet)->tet()->getVertex(3)->x(), -// (*ittet)->tet()->getVertex(3)->y(), -// (*ittet)->tet()->getVertex(3)->z()); -// if(!(*ittet)->inCircumSphere ( v ))throw; ++ittet; } -// fprintf(ff2,"};\n"); -// fclose(ff2); -// Msg::Info("cavity of size %d volume %g",cavity.size(),oldVolume); - // create new tetrahedron using faces that are - // on the border of the cavity - // add those to a list - // add also tets that are on the other side of the face - // in order to perform the connexions afterwards - -// char name[245]; -// sprintf(name,"test%d.pos",III); - -// FILE *ff = fopen(name,"w"); -// fprintf(ff,"View\"test\"{\n"); MTet4** newTets = new MTet4*[shell.size()];; int k = 0; std::list<faceXtet>::iterator it = shell.begin(); + bool onePointIsTooClose = false; while (it != shell.end()){ MTetrahedron *tr = new MTetrahedron(it->v[0], it->v[1], it->v[2], v); - // Msg::Info("shell %d %d %d",it->v[0]->getNum(),it->v[1]->getNum(),it->v[2]->getNum()); -// fprintf(ff,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0};\n", -// it->v[0]->x(), -// it->v[0]->y(), -// it->v[0]->z(), -// it->v[1]->x(), -// it->v[1]->y(), -// it->v[1]->z(), -// it->v[2]->x(), -// it->v[2]->y(), -// it->v[2]->z()); - + + const double ONE_THIRD = 1./3.; + double lc = .25 * (vSizes[tr->getVertex(0)->getIndex()] + + vSizes[tr->getVertex(1)->getIndex()] + + vSizes[tr->getVertex(2)->getIndex()] + + vSizes[tr->getVertex(3)->getIndex()]); + double lcBGM = .25 * (vSizesBGM[tr->getVertex(0)->getIndex()] + + vSizesBGM[tr->getVertex(1)->getIndex()] + + vSizesBGM[tr->getVertex(2)->getIndex()] + + vSizesBGM[tr->getVertex(3)->getIndex()]); + double LL = std::min(lc, lcBGM); + MTet4 *t4 = myFactory.Create(tr, vSizes, vSizesBGM); - t4->setOnWhat(t->onWhat()); - newTets[k++] = t4; - // all new tets are pushed front in order to ba able to destroy - // them if the cavity is not star shaped around the new vertex. - // here, we better use robust perdicates that implies to orient - // all faces and ensure that the tets are all oriented the same. - new_cavity.push_back(t4); - MTet4 *otherSide = it->t1->getNeigh(it->i1); - - if (otherSide) - new_cavity.push_back(otherSide); - // if (!it->t1->isDeleted())throw; - newVolume += fabs(t4->getVolume()); - ++it; - } -// fprintf(ff,"};\n"); -// fclose (ff); -// Msg::Info("new cavity of vol %g (%d boundaries)",newVolume,shell.size()); + t4->setOnWhat(t->onWhat()); + + double d1 = sqrt((it->v[0]->x() - v->x()) * (it->v[0]->x() - v->x()) + + (it->v[0]->y() - v->y()) * (it->v[0]->y() - v->y()) + + (it->v[0]->z() - v->z()) * (it->v[0]->z() - v->z())); + double d2 = sqrt((it->v[1]->x() - v->x()) * (it->v[1]->x() - v->x()) + + (it->v[1]->y() - v->y()) * (it->v[1]->y() - v->y()) + + (it->v[1]->z() - v->z()) * (it->v[1]->z() - v->z())); + double d3 = sqrt((it->v[2]->x() - v->x()) * (it->v[2]->x() - v->x()) + + (it->v[2]->y() - v->y()) * (it->v[2]->y() - v->y()) + + (it->v[2]->z() - v->z()) * (it->v[2]->z() - v->z())); + + if (d1 < LL * .25 || d2 < LL * .25 || d3 < LL * .25) onePointIsTooClose = true; + newTets[k++] = t4; + // all new tets are pushed front in order to ba able to destroy + // them if the cavity is not star shaped around the new vertex. + // here, we better use robust perdicates that implies to orient + // all faces and ensure that the tets are all oriented the same. + new_cavity.push_back(t4); + MTet4 *otherSide = it->t1->getNeigh(it->i1); + + if (otherSide) + new_cavity.push_back(otherSide); + // if (!it->t1->isDeleted())throw; + newVolume += fabs(t4->getVolume()); + ++it; + } // OK, the cavity is star shaped - if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume){ + if (fabs(oldVolume - newVolume) < 1.e-10 * oldVolume && + !onePointIsTooClose){ connectTets(new_cavity.begin(), new_cavity.end()); allTets.insert(newTets, newTets + shell.size()); - -// ittet = cavity.begin(); -// ittete = cavity.end(); -// while ( ittet != ittete ){ -// myFactory.Free (*ittet); -// ++ittet; -// } + + if (activeTets){ + for (std::list<MTet4*>::iterator i = new_cavity.begin(); i != new_cavity.end(); ++i){ + int active_face; + if(isActive(*i, LIMIT_, active_face) && (*i)->getRadius() > LIMIT_){ + if ((*activeTets).find(*i) == (*activeTets).end()) + (*activeTets).insert(*i); + } + } + } + delete [] newTets; + return true; } else { // The cavity is NOT star shaped @@ -840,6 +870,21 @@ void insertVerticesInRegion (GRegion *gr) Msg::Info("cleaning up the memory %d -> %d", n1, allTets.size()); } } + + // relocate vertices + int nbReloc = 0; + for (int SM=0;SM<CTX::instance()->mesh.nbSmoothing;SM++){ + for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){ + if (!(*it)->isDeleted()){ + double qq = (*it)->getQuality(); + if (qq < .4) + for (int i = 0; i < 4; i++){ + if (smoothVertex(*it, i, QMTET_2)) nbReloc++; + } + } + } + } + while(1){ if(allTets.begin() == allTets.end()) break; @@ -851,6 +896,230 @@ void insertVerticesInRegion (GRegion *gr) myFactory.Free(worst); allTets.erase(allTets.begin()); } +} + +MVertex * optimalPointFrontal (GRegion *gr, + MTet4 *worst, + int active_face, + std::vector<double> &vSizes, + std::vector<double> &vSizesBGM){ + double centerTet[3], centerFace[3]; + MTetrahedron *base = worst->tet(); + faceXtet fxt ( worst, active_face ); + double pa[3] = {fxt.v[0]->x(),fxt.v[0]->y(),fxt.v[0]->z()}; + double pb[3] = {fxt.v[1]->x(),fxt.v[1]->y(),fxt.v[1]->z()}; + double pc[3] = {fxt.v[2]->x(),fxt.v[2]->y(),fxt.v[2]->z()}; + circumCenterXYZ(pa, pb, pc, centerFace); + worst->circumcenter(centerTet); + + SVector3 dir (centerTet[0] - centerFace[0], + centerTet[1] - centerFace[1], + centerTet[2] - centerFace[2]); + + const double q = dir.norm(); + dir.normalize(); + + SVector3 rDir (pa[0] - centerFace[0], + pa[1] - centerFace[1], + pa[2] - centerFace[2]); + + const double p = 0.5 * rDir.norm(); + + const double rhoM1 = 0.33333 * (vSizes[fxt.v[0]->getIndex()] + + vSizes[fxt.v[1]->getIndex()] + + vSizes[fxt.v[2]->getIndex()] ); + const double rhoM2 = 0.33333 * (vSizesBGM[fxt.v[0]->getIndex()] + + vSizesBGM[fxt.v[1]->getIndex()] + + vSizesBGM[fxt.v[2]->getIndex()] ); + const double rhoM = std::min(rhoM1, rhoM2); + + const double HEIGHT = 1/sqrt(3.); + + const double rhoM_hat = std::min(std::max(rhoM, p), (p * p + q * q) / (2 * q)); + const double d = (rhoM_hat + sqrt (rhoM_hat * rhoM_hat - p * p)) * HEIGHT; + + // const double a = 2*p *3 /sqrt(3); + const double a = .025; + const double tt = a*sqrt(6.)/3; + MVertex *vert = new MVertex(centerFace[0] + tt * dir[0], + centerFace[1] + tt * dir[1], + centerFace[2] + tt * dir[2], + gr); + return vert; } + + +void bowyerWatsonFrontalLayers(GRegion *gr, bool hex) +{ + + std::vector<double> vSizes; + std::vector<double> vSizesBGM; + MTet4Factory myFactory(1600000); + std::set<MTet4*, compareTet4Ptr> &allTets = myFactory.getAllTets(); + std::set<MTet4*, compareTet4Ptr> activeTets; + int NUM = 0; + + if (!backgroundMesh::current()) { + // TODO !!! + } + + if (hex){ + LIMIT_ = sqrt(2)*.99; + MTet4::radiusNorm =-1; + } + + { // leave this in a block so the map gets deallocated directly + std::map<MVertex*, double> vSizesMap; + for(unsigned int i = 0; i < gr->tetrahedra.size(); i++) + setLcs(gr->tetrahedra[i], vSizesMap); + for(std::map<MVertex*, double>::iterator it = vSizesMap.begin(); + it != vSizesMap.end(); ++it){ + it->first->setIndex(NUM++); + vSizes.push_back(it->second); + vSizesBGM.push_back(it->second); + } + } + + for(unsigned int i = 0; i < gr->tetrahedra.size(); i++) + allTets.insert(myFactory.Create(gr->tetrahedra[i], vSizes,vSizesBGM)); + + gr->tetrahedra.clear(); + connectTets(allTets.begin(), allTets.end()); + + fs_cont search; + buildFaceSearchStructure(gr->model(), search); + + for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){ + if(!(*it)->onWhat()){ + std::list<MTet4*> theRegion; + std::set<GFace *> faces_bound; + GRegion *bidon = (GRegion*)123; + double _t1 = Cpu(); + Msg::Debug("start with a non classified tet"); + recur_classify(*it, theRegion, faces_bound, bidon, gr->model(), search); + double _t2 = Cpu(); + Msg::Debug("found %d tets with %d faces (%g sec for the classification)", + theRegion.size(), faces_bound.size(), _t2 - _t1); + GRegion *myGRegion = getRegionFromBoundingFaces(gr->model(), faces_bound); + // Msg::Info("a region is found %p",myGRegion); + if(myGRegion) // a geometrical region associated to the list of faces has been found + for(std::list<MTet4*>::iterator it2 = theRegion.begin(); + it2 != theRegion.end(); ++it2) (*it2)->setOnWhat(myGRegion); + else // the tets are in the void + for(std::list<MTet4*>::iterator it2 = theRegion.begin(); + it2 != theRegion.end(); ++it2)(*it2)->setDeleted(true); + } + } + search.clear(); + + for(MTet4Factory::iterator it = allTets.begin(); it!=allTets.end(); ++it){ + (*it)->setNeigh(0, 0); + (*it)->setNeigh(1, 0); + (*it)->setNeigh(2, 0); + (*it)->setNeigh(3, 0); + } + connectTets(allTets.begin(), allTets.end()); + + int ITER = 0, active_face; + + std::set<MFace,Less_Face> _front; + for(MTet4Factory::iterator it = allTets.begin(); it!=allTets.end(); ++it){ + if(isActive(*it,LIMIT_,active_face) && (*it)->getRadius() > LIMIT_){ + activeTets.insert(*it); + updateActiveFaces(*it, LIMIT_, _front); + } + else if ((*it)->getRadius() < LIMIT_)break; + } + + // insert points + int ITERATION = 1; + while (1){ + if (ITERATION == 8)break; + ITERATION ++; + + std::set<MTet4*, compareTet4Ptr> activeTetsNotInFront; + + while (1){ + + if (!activeTets.size())break; + + // printf("%d active tets %d tets\n",activeTets.size(),allTets.size()); + + std::set<MTet4*,compareTet4Ptr>::iterator WORST_ITER = activeTets.begin(); + MTet4 *worst = (*WORST_ITER); + if(worst->isDeleted()){ + activeTets.erase(WORST_ITER); + // myFactory.Free(worst); + } + else { + activeTets.erase(WORST_ITER); + if (isActive(worst, LIMIT_, active_face,&_front) && + worst->getRadius() > LIMIT_){ + // printf("worst = %12.5E\n",worst->getRadius()); + + if(ITER++ % 5000 == 0) + Msg::Info("%d points created -- Worst tet radius is %g", + vSizes.size(), worst->getRadius()); + + MVertex *v = optimalPointFrontal (gr,worst,active_face,vSizes,vSizesBGM); + v->setIndex(NUM++); + vSizes.push_back(.025); + vSizesBGM.push_back(.025); + + if(!worst->inCircumSphere(v) || + !insertVertex(v, worst, myFactory, allTets, vSizes,vSizesBGM,&activeTets)){ + myFactory.changeTetRadius(allTets.begin(), 0.); + if(v) delete v; + } + else{ + // printf("yeah ! one new vertex \n"); + v->onWhat()->mesh_vertices.push_back(v); + // if (ITER == 100)break; + } + } + else if (worst->getRadius() > LIMIT_){ + activeTetsNotInFront.insert(worst); + } + } + } + _front.clear(); + MTet4Factory::iterator it = activeTetsNotInFront.begin(); + for ( ; it!=activeTetsNotInFront.end();++it){ + if((*it)->getRadius() > LIMIT_ && isActive(*it,LIMIT_,active_face)){ + activeTets.insert(*it); + updateActiveFaces(*it, LIMIT_, _front); + } + } + if (!activeTets.size())break; + } + + + int nbReloc = 0; + for (int SM=0;SM<CTX::instance()->mesh.nbSmoothing;SM++){ + for(MTet4Factory::iterator it = allTets.begin(); it != allTets.end(); ++it){ + if (!(*it)->isDeleted()){ + double qq = (*it)->getQuality(); + if (qq < .4) + for (int i = 0; i < 4; i++){ + if (smoothVertex(*it, i, QMTET_2)) nbReloc++; + } + } + } + } + + + while(1){ + if(allTets.begin() == allTets.end()) break; + MTet4 *worst = *allTets.begin(); + if(!worst->isDeleted()){ + worst->onWhat()->tetrahedra.push_back(worst->tet()); + worst->tet() = 0; + } + myFactory.Free(worst); + allTets.erase(allTets.begin()); + } + MTet4::radiusNorm = 2; + LIMIT_ = 1; +} diff --git a/Mesh/meshGRegionDelaunayInsertion.h b/Mesh/meshGRegionDelaunayInsertion.h index 2e20470e75..cdd9b581a3 100644 --- a/Mesh/meshGRegionDelaunayInsertion.h +++ b/Mesh/meshGRegionDelaunayInsertion.h @@ -55,6 +55,7 @@ class MTet4 MTet4 *neigh[4]; GRegion *gr; public : + static int radiusNorm; // 2 is euclidian norm, -1 is infinite norm ~MTet4(){} MTet4() : deleted(false), circum_radius(0.0), base(0), gr(0) @@ -170,6 +171,7 @@ class MTet4 void connectTets(std::list<MTet4*> &); void connectTets(std::vector<MTet4*> &); void insertVerticesInRegion(GRegion *gr); +void bowyerWatsonFrontalLayers(GRegion *gr, bool hex); class compareTet4Ptr { diff --git a/Mesh/meshGRegionMMG3D.cpp b/Mesh/meshGRegionMMG3D.cpp new file mode 100644 index 0000000000..4b8ae84bcd --- /dev/null +++ b/Mesh/meshGRegionMMG3D.cpp @@ -0,0 +1,153 @@ +#include "GmshConfig.h" +#include "meshGRegionMMG3D.h" +#ifdef HAVE_MMG3D +#include <set> +#include "GRegion.h" +#include "GFace.h" +#include "MTetrahedron.h" +#include "MTriangle.h" +#include "MVertex.h" +#include "BackgroundMesh.h" + +extern "C" { +#include <libmmg3d.h> +#define M_UNUSED (1 << 0) +} + +void MMG2gmsh (GRegion *gr, MMG_pMesh mmg, std::map<int,MVertex*> &mmg2gmsh){ + printf("%d vertices in MMG\n",mmg->np); + for (int k=1;k<= mmg->np ; k++){ + MMG_pPoint ppt = &mmg->point[k]; + if (ppt->tag & M_UNUSED) continue; + if (mmg2gmsh.find(k) == mmg2gmsh.end()){ + MVertex *v = new MVertex(ppt->c[0],ppt->c[1],ppt->c[2],gr); + mmg2gmsh[k] = v; + gr->mesh_vertices.push_back(v); + } + } + + + for (int k=1; k<=mmg->ne; k++) { + MMG_pTetra ptetra = &mmg->tetra[k]; + if ( ptetra->v[0] ){ + MVertex *v1 = mmg2gmsh[ptetra->v[0]]; + MVertex *v2 = mmg2gmsh[ptetra->v[1]]; + MVertex *v3 = mmg2gmsh[ptetra->v[2]]; + MVertex *v4 = mmg2gmsh[ptetra->v[3]]; + if (!v1 || !v2 || !v3 || !v4){ + Msg::Error("Element %d Unknown Vertex in MMG2gmsh %d(%p) %d(%p) %d(%p) %d(%p)",k,ptetra->v[0],v1,ptetra->v[1],v2,ptetra->v[2],v3,ptetra->v[3],v4); + } + else gr->tetrahedra.push_back(new MTetrahedron(v1,v2,v3,v4)); + } + } +} + +void gmsh2MMG (GRegion *gr, MMG_pMesh mmg, MMG_pSol sol, std::map<int,MVertex*> &mmg2gmsh){ + mmg->ne = gr->tetrahedra.size(); + std::set<MVertex*> allVertices; + for (int i=0;i< gr->tetrahedra.size() ; i++){ + allVertices.insert(gr->tetrahedra[i]->getVertex(0)); + allVertices.insert(gr->tetrahedra[i]->getVertex(1)); + allVertices.insert(gr->tetrahedra[i]->getVertex(2)); + allVertices.insert(gr->tetrahedra[i]->getVertex(3)); + } + mmg->np = sol->np = allVertices.size(); + + std::list<GFace*> f = gr->faces(); + + mmg->nt = 0; + for (std::list<GFace*>::iterator it = f.begin(); it != f.end() ; ++it){ + mmg->nt += (*it)->triangles.size(); + } + + mmg->npmax = sol->npmax = 1000000; + mmg->ntmax = 700000; + mmg->nemax = 7000000; + + mmg->point = (MMG_pPoint)calloc(mmg->npmax+1,sizeof(MMG_Point)); + mmg->tetra = (MMG_pTetra)calloc(mmg->nemax+1,sizeof(MMG_Tetra)); + mmg->tria = (MMG_pTria) calloc(mmg->ntmax+1,sizeof(MMG_Tria)); + mmg->disp = (MMG_pDispl)calloc(mmg->npmax+1,sizeof(MMG_Displ)); + mmg->adja = (int*)calloc(4*mmg->nemax+5,sizeof(int)); + + sol->offset = 1; + sol->met = (double*)calloc(sol->npmax+1,sol->offset*sizeof(double)); + + int k=1; + std::map<int,int> gmsh2mmg_num; + for (std::set<MVertex*>::iterator it = allVertices.begin() ; it != allVertices.end() ; ++it){ + MMG_pPoint ppt = &mmg->point[k]; + + mmg2gmsh[k] = *it; + + ppt->c[0] = (*it)->x(); + ppt->c[1] = (*it)->y(); + ppt->c[2] = (*it)->z(); + ppt->ref = gr->tag(); + gmsh2mmg_num[(*it)->getNum()] = k; + + MVertex *v = *it; + double U=0,V=0; + if (v->onWhat()->dim() == 1){ + v->getParameter(0,U); + } + else if (v->onWhat()->dim() == 2){ + v->getParameter(0,U); + v->getParameter(1,V); + } + double lc = BGM_MeshSize(v->onWhat(), U,V,v->x(), v->y(), v->z()); + int isol = (k-1) * sol->offset + 1; + for (int i=0; i<sol->offset; i++) { + sol->met[isol + i] = lc; + // printf("sol[%d] = %12.5E\n",isol + i,lc); + } + k++; + } + + for (k=1; k<=mmg->ne; k++) { + MMG_pTetra ptetra = &mmg->tetra[k]; + ptetra->v[0] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(0)->getNum()]; + ptetra->v[1] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(1)->getNum()]; + ptetra->v[2] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(2)->getNum()]; + ptetra->v[3] = gmsh2mmg_num[gr->tetrahedra[k-1]->getVertex(3)->getNum()]; + ptetra->ref = gr->tag(); + } + + k = 1; + for (std::list<GFace*>::iterator it = f.begin(); it != f.end() ; ++it){ + for (int i=0;i<(*it)->triangles.size();i++){ + MMG_pTria ptriangle = &mmg->tria[k]; + ptriangle->v[0] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(0)->getNum()]; + ptriangle->v[1] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(1)->getNum()]; + ptriangle->v[2] = gmsh2mmg_num[(*it)->triangles[i]->getVertex(2)->getNum()]; + ptriangle->ref = (*it)->tag(); + k++; + } + } + mmg->disp = 0; + +} + +void refineMeshMMG(GRegion *gr){ + MMG_pMesh mmg = (MMG_pMesh)calloc(1,sizeof(MMG_Mesh)); + MMG_pSol sol = (MMG_pSol)calloc(1,sizeof(MMG_Sol)); + std::map<int,MVertex*> mmg2gmsh; + gmsh2MMG (gr, mmg, sol,mmg2gmsh); + int opt[9] = {1,0,64,0,0,(Msg::GetVerbosity() > 20) ? 3 : -1,0,0,0}; + mmg3d::MMG_mmg3dlib(opt,mmg,sol); + + for (int i=0;i<gr->tetrahedra.size();++i)delete gr->tetrahedra[i]; + gr->tetrahedra.clear(); + for (int i=0;i<gr->mesh_vertices.size();++i)delete gr->mesh_vertices[i]; + gr->mesh_vertices.clear(); + + + MMG2gmsh (gr, mmg, mmg2gmsh); + MMG_saveMesh(mmg ,"test.mesh"); +} + +#else +void refineMeshMMG(GRegion *gr){ + Msg::Error("You should compile your version of Gmsh with MMG3D, the Mobile Mesh Generator"); +} +#endif diff --git a/Mesh/meshGRegionMMG3D.h b/Mesh/meshGRegionMMG3D.h new file mode 100644 index 0000000000..59c50d6c20 --- /dev/null +++ b/Mesh/meshGRegionMMG3D.h @@ -0,0 +1,5 @@ +#ifndef _MESHGREGIONMMG3D_H_ +#define _MESHGREGIONMMG3D_H_ +class GRegion; +void refineMeshMMG(GRegion *gr); +#endif diff --git a/benchmarks/3d/coin.geo b/benchmarks/3d/coin.geo index cc49a2b262..ba4c91c060 100644 --- a/benchmarks/3d/coin.geo +++ b/benchmarks/3d/coin.geo @@ -14,8 +14,9 @@ 0.085 261542 1568048 1285.29 */ lcar1 = .2; +lcar2 = .2; -Point(newp) = {0.5,0.5,0.5,lcar1}; /* Point 1 */ +Point(newp) = {0.5,0.5,0.5,lcar2}; /* Point 1 */ Point(newp) = {0.5,0.5,0,lcar1}; /* Point 2 */ Point(newp) = {0,0.5,0.5,lcar1}; /* Point 3 */ Point(newp) = {0,0,0.5,lcar1}; /* Point 4 */ diff --git a/benchmarks/3d/thai.geo b/benchmarks/3d/thai.geo index dff1f8df15..1e90077968 100644 --- a/benchmarks/3d/thai.geo +++ b/benchmarks/3d/thai.geo @@ -1,3 +1,5 @@ +Mesh.RecombineAll=1; +Mesh.RecombinationAlgorithm=1; Point(1) = {3.42295068244, 47, -7.5, 1e+022}; Point(2) = {3.42295068244, 58, -7.5, 1e+022}; Point(3) = {-3.5, 47, -7.5, 1e+022}; @@ -2428,3 +2430,4 @@ Line Loop(2032) = {2021, -184, -266, 268, 2019, 2020}; Plane Surface(2033) = {2032}; Surface Loop(2035) = {309, 282, 288, 349, 297, 295, 290, 2014, 2012, 325, 377, 2023, 2025, 429, 425, 435, 437, 439, 427, 441, 443, 445, 449, 453, 451, 447, 457, 455, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480, 482, 484, 395, 418, 405, 420, 422, 375, 391, 393, 389, 397, 399, 2033, 2027, 379, 304, 280, 284, 2016, 2018, 299, 321, 347, 2029, 2031, 385, 383, 286, 293, 311, 313, 2010, 337, 339, 335, 341, 371, 365, 367, 369, 363, 373, 381, 416, 408, 414, 410, 412, 2008, 431, 433, 333, 327, 331, 329, 353, 361, 355, 357, 359, 351, 317, 315}; Volume(2036) = {2035}; +Recombine Surface {405, 375, 418, 420, 422, 2023, 425, 325, 377, 297, 445, 443, 455, 449, 295, 2012, 460, 474, 453, 480, 439, 435, 470, 468, 429, 2008, 482, 357, 355, 331, 353, 464, 351, 333, 349, 282, 290, 288, 447, 441, 412, 462, 427, 408, 457, 410, 431, 451, 433, 437, 309, 315, 317, 327, 329, 359, 361, 2014, 2025, 484, 466, 472, 476, 478, 381, 304, 379, 2027, 286, 284, 280, 2016, 293, 311, 313, 347, 373, 2010, 371, 369, 367, 335, 337, 299, 2029, 2018, 341, 339, 321, 365, 363, 395, 399, 397, 2033, 383, 389, 391, 393, 414, 416, 385, 2031}; diff --git a/benchmarks/step/capot.geo b/benchmarks/step/capot.geo index d2ba4152d7..c49a17d9d4 100644 --- a/benchmarks/step/capot.geo +++ b/benchmarks/step/capot.geo @@ -1,7 +1,13 @@ Mesh.RemeshParametrization=1; //(0) harmonic (1) conformal Mesh.RemeshAlgorithm=0; //(0) nosplit (1) automatic (2) split metis -Mesh.CharacteristicLengthFactor=0.2; +Mesh.Algorithm = 8; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg) +Mesh.RecombinationAlgorithm = 1; + + + + +//Mesh.CharacteristicLengthFactor=0.2; Merge "capot.brep"; Compound Line(1000) = {47,50}; @@ -10,3 +16,4 @@ Compound Line(1001) = {44,46}; Compound Surface(100) = {1, 8, 15, 17, 16, 18, 9, 2, 3, 10, 7, 14, 11, 4, 12, 5, 6, 13} ; Physical Surface(100)={100}; +Recombine Surface {100}; diff --git a/benchmarks/stl/mobilette.geo b/benchmarks/stl/mobilette.geo index 43a248c0cd..96dd603053 100644 --- a/benchmarks/stl/mobilette.geo +++ b/benchmarks/stl/mobilette.geo @@ -1,4 +1,4 @@ -Mesh.Algorithm = 6; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg) +Mesh.Algorithm = 8; //(1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=bamg) Mesh.CharacteristicLengthMin=1.5/2; Mesh.CharacteristicLengthMax=2.5/2; Mesh.RemeshAlgorithm=1; @@ -26,5 +26,8 @@ EndFor Surface Loop(1) = {s : s + #ss[]-1}; Volume(1) = {1}; +Mesh.RecombineAll=1; +Mesh.RecombinationAlgorithm=1; + Physical Surface(1) = {s : s + #ss[]-1}; Physical Volume(1) = 1; diff --git a/contrib/mmg3d/CMakeLists.txt b/contrib/mmg3d/CMakeLists.txt new file mode 100644 index 0000000000..0700016978 --- /dev/null +++ b/contrib/mmg3d/CMakeLists.txt @@ -0,0 +1,69 @@ +# Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle +# +# See the LICENSE.txt file for license information. Please report all +# bugs and problems to <gmsh@geuz.org>. + +set(SRC +./build/sources/mmg3d.c +./build/sources/inout.c +./build/sources/mmg3dlib.c +./build/sources/scalem.c +./build/sources/outqua.c +./build/sources/baryct.c +./build/sources/zaldy.c +./build/sources/typelt.c +./build/sources/swaptet.c +./build/sources/swapar.c +./build/sources/swap710.c +./build/sources/swap68.c +./build/sources/swap56.c +./build/sources/swap44.c +./build/sources/swap23.c +./build/sources/spledg.c +./build/sources/solmap.c +./build/sources/simu710.c +./build/sources/simu68.c +./build/sources/simu56.c +./build/sources/simu44.c +./build/sources/simu23.c +./build/sources/ratio.c +./build/sources/queue.c +./build/sources/quality.c +./build/sources/pattern.c +./build/sources/opttyp.c +./build/sources/opttet.c +./build/sources/optra4.c +./build/sources/optlentet.c +./build/sources/optlen.c +./build/sources/optlap.c +./build/sources/optcte.c +./build/sources/optcoq.c +./build/sources/optbdry.c +./build/sources/movevertex.c +./build/sources/mmg3d9.c +./build/sources/delaunay.c +./build/sources/hash.c +./build/sources/length.c +./build/sources/mmg3d4.c +./build/sources/mmg3d1.c +./build/sources/memory.c +./build/sources/matrix.c +./build/sources/locate.c +./build/sources/librnbg.c +./build/sources/heap.c +./build/sources/eigenv.c +./build/sources/cutelt.c +./build/sources/coquil.c +./build/sources/colpoi.c +./build/sources/chrono.c +./build/sources/chkmsh.c +./build/sources/cenrad.c +./build/sources/cendel.c +./build/sources/bucket.c +./build/sources/boulep.c +./build/sources/analarcutting.c +./build/sources/analar.c +) + +file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) +append_gmsh_src(contrib/mmg3d "${SRC};${HDR}") diff --git a/contrib/mmg3d/INSTALL.txt b/contrib/mmg3d/INSTALL.txt new file mode 100644 index 0000000000..14d9f7844f --- /dev/null +++ b/contrib/mmg3d/INSTALL.txt @@ -0,0 +1,40 @@ +MMG3D 4.0 installation instructions +==================================== + +The simplest way to compile is to use cmake : + +1) The cmake tool is available at this adress : + +http://www.cmake.org/ + +2) 'cd' to the directory build/ containing : +CMakeLists.txt +a directory named sources/ containing all the MMG3D files. + +3) Configure and create the makefile with cmake : + +By default, the configuration is done to create an executable +of MMG3D. + +NB : By default, cmake find Scotch software : +http://www.labri.fr/perso/pelegrin/scotch/scotch_en.html + +i) If you use the gui interface of cmake : 'cmake-gui' +You can specify if you would compile the shared or static library +and if you have or not Scotch software. + +OR + +ii) 'cmake . ' +You can specify the following option : +-DCOMPIL_STATIC_LIBRARY="ON" or -DCOMPIL_SHARED_LIBRARY="ON" +(by default : OFF) +-DUSE_SCOTCH="OFF" ' (by default : ON) + + + +4) Compile MMG3D : +'make' + + + diff --git a/contrib/mmg3d/LICENCE.txt b/contrib/mmg3d/LICENCE.txt new file mode 100644 index 0000000000..e587591e14 --- /dev/null +++ b/contrib/mmg3d/LICENCE.txt @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/contrib/mmg3d/README.txt b/contrib/mmg3d/README.txt new file mode 100644 index 0000000000..c296704020 --- /dev/null +++ b/contrib/mmg3d/README.txt @@ -0,0 +1,8 @@ +The terms under which this copy of the MMG3d 4.0 distribution +is provided to you are described in file "LICENSE.txt", located +in the same directory as this file. + +If you accept them, please refer to file "INSTALL.txt", also +located in this directory, for the installation instructions. + + diff --git a/contrib/mmg3d/build/CMakeLists.txt b/contrib/mmg3d/build/CMakeLists.txt new file mode 100644 index 0000000000..1db395f167 --- /dev/null +++ b/contrib/mmg3d/build/CMakeLists.txt @@ -0,0 +1,98 @@ +cmake_minimum_required (VERSION 2.6) +project (MMG3D) + +IF(APPLE) + add_definitions(-static-libgcc -mmacosx-version-min=10.4 -arch ppc -arch i386) + + # determine if the processor supports 64bit execution + EXECUTE_PROCESS( + COMMAND sysctl hw.cpu64bit_capable + ERROR_QUIET + OUTPUT_VARIABLE 64_CMD + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + STRING(REGEX REPLACE "^hw.cpu64bit_capable: (.*)" "\\1" 64_BIT "${64_CMD}") + #otherwise pbs with linkage SCOTCH + SET(CMAKE_OSX_ARCHITECTURES ppc) + + # display the results + MESSAGE(STATUS "CMAKE_OSX_ARCHITECTURES: " ${CMAKE_OSX_ARCHITECTURES}) +ENDIF(APPLE) + + + +# should we use SCOTCH +option (USE_SCOTCH + "Use SCOTCH TOOL for renumbering" ON) + +# configure a header file to pass some of the CMake settings +# to the source code +configure_file ( + "sources/mmg3dConfig.h.in" + "sources/mmg3dConfig.h" + ) + +# add SCOTCH library? +# +if (USE_SCOTCH) + #Inclusion de SCOTCH + find_library(LIBS_SCOTCH scotch) + find_library(LIBS_SCOTCHERR scotcherr) + find_path(INCLUDE_SCOTCH scotch.h) + # IF(LIBS_SCOTCH_FOUND) + # MESSAGE(STATUS "Looking for SCOTCH - found") + # ELSE(SCOTCH_FOUND) + # MESSAGE(STATUS "Looking for SCOTCH - not found") + # ENDIF(SCOTCH_FOUND) + include_directories(${INCLUDE_SCOTCH}) +endif (USE_SCOTCH) + +#file sources +file( + GLOB_RECURSE + source_files + sources/* +) + +add_executable(mmg3d4.0 ${source_files}) + +option (COMPIL_STATIC_LIBRARY + "Use tutorial provided math implementation" OFF) +if (COMPIL_STATIC_LIBRARY) + add_library(mmg3dlib4.0 STATIC ${source_files}) + target_link_libraries(mmg3dlib4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR}) +endif (COMPIL_STATIC_LIBRARY) +option (COMPIL_SHARED_LIBRARY + "Use tutorial provided math implementation" OFF) +if (COMPIL_SHARED_LIBRARY) + add_library(mmg3dlib4.0 SHARED ${source_files}) + target_link_libraries(mmg3dlib4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR}) +endif (COMPIL_SHARED_LIBRARY) + +find_library(M_LIB m) +target_link_libraries(mmg3d4.0 ${M_LIB} ${LIBS_SCOTCH} ${LIBS_SCOTCHERR}) + +#add testlib +if (COMPIL_STATIC_LIBRARY) + #file sources + file( + GLOB_RECURSE + source_testlib + libexamples/* + ) + add_executable(testlib ${source_testlib}) + include_directories(sources/) + target_link_libraries(testlib mmg3dlib4.0) +endif (COMPIL_STATIC_LIBRARY) + +if (COMPIL_SHARED_LIBRARY) + #file sources + file( + GLOB_RECURSE + source_testlib + libexamples/* + ) + add_executable(testlib ${source_testlib}) + include_directories(sources/) + target_link_libraries(testlib mmg3dlib4.0) +endif (COMPIL_SHARED_LIBRARY) diff --git a/contrib/mmg3d/build/libexamples/main.c b/contrib/mmg3d/build/libexamples/main.c new file mode 100644 index 0000000000..f9e29257ec --- /dev/null +++ b/contrib/mmg3d/build/libexamples/main.c @@ -0,0 +1,129 @@ +/*Authors Cécile Dobrzynski + +Example for using mmg3dlib + +*/ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <ctype.h> +#include <math.h> +#include <float.h> + +#include "libmmg3d.h" +int main(int argc,char *argv[]) { + MMG_pMesh mmgMesh; + MMG_pSol mmgSol; + int opt[9],k; + + fprintf(stdout," -- TEST MMG3DLIB \n"); + + mmgMesh = (MMG_pMesh)calloc(1,sizeof(MMG_Mesh)); + assert(mmgMesh); + + /* allocation */ + mmgMesh->np = 12; + mmgMesh->nt = 0; + mmgMesh->ne = 12; + + + mmgMesh->npmax = 500000; + mmgMesh->ntmax = 1000000; + mmgMesh->nemax = 3000000; + + mmgMesh->point = (MMG_pPoint)calloc(mmgMesh->npmax+1,sizeof(MMG_Point)); + assert(mmgMesh->point); + mmgMesh->tetra = (MMG_pTetra)calloc(mmgMesh->nemax+1,sizeof(MMG_Tetra)); + assert(mmgMesh->tetra); + mmgMesh->tria = (MMG_pTria)calloc(mmgMesh->ntmax+1,sizeof(MMG_Tria)); + assert(mmgMesh->tria); + mmgMesh->adja = (int*)calloc(4*mmgMesh->nemax+5,sizeof(int)); + assert(mmgMesh->adja); + mmgMesh->disp = (MMG_pDispl)calloc(1,sizeof(MMG_Displ)); + assert(mmgMesh->disp); + mmgMesh->disp->mv = (double*)calloc(3*(mmgMesh->npmax + 1),sizeof(double)); + assert(mmgMesh->disp->mv); + mmgMesh->disp->alpha = (short*)calloc(mmgMesh->npmax+1,sizeof(short)); + assert(mmgMesh->disp->alpha); + + /*coordinates vertices*/ + mmgMesh->point[1].c[0] = 0.; mmgMesh->point[1].c[1] = 0.; mmgMesh->point[1].c[2] = 0.; mmgMesh->point[1].ref = 0; + mmgMesh->point[2].c[0] = 0.5; mmgMesh->point[2].c[1] = 0; mmgMesh->point[2].c[2] = 0; mmgMesh->point[2].ref = 0; + mmgMesh->point[3].c[0] = 0.5; mmgMesh->point[3].c[1] = 0; mmgMesh->point[3].c[2] = 1; mmgMesh->point[3].ref = 0; + mmgMesh->point[4].c[0] = 0; mmgMesh->point[4].c[1] = 0; mmgMesh->point[4].c[2] = 1; mmgMesh->point[4].ref = 0; + mmgMesh->point[5].c[0] = 0; mmgMesh->point[5].c[1] = 1; mmgMesh->point[5].c[2] = 0; mmgMesh->point[5].ref = 0; + mmgMesh->point[6].c[0] = 0.5; mmgMesh->point[6].c[1] = 1; mmgMesh->point[6].c[2] = 0; mmgMesh->point[6].ref = 0; + mmgMesh->point[7].c[0] = 0.5; mmgMesh->point[7].c[1] = 1; mmgMesh->point[7].c[2] = 1; mmgMesh->point[7].ref = 0; + mmgMesh->point[8].c[0] = 0; mmgMesh->point[8].c[1] = 1; mmgMesh->point[8].c[2] = 1; mmgMesh->point[8].ref = 0; + mmgMesh->point[9].c[0] = 1; mmgMesh->point[9].c[1] = 0; mmgMesh->point[9].c[2] = 0; mmgMesh->point[9].ref = 0; + mmgMesh->point[10].c[0] = 1; mmgMesh->point[10].c[1] = 1; mmgMesh->point[10].c[2] = 0; mmgMesh->point[10].ref = 0; + mmgMesh->point[11].c[0] = 1; mmgMesh->point[11].c[1] = 0; mmgMesh->point[11].c[2] = 1; mmgMesh->point[11].ref = 0; + mmgMesh->point[12].c[0] = 1; mmgMesh->point[12].c[1] = 1; mmgMesh->point[12].c[2] = 1; mmgMesh->point[12].ref = 0; + + /*tetra*/ + mmgMesh->tetra[1].v[0] = 1; mmgMesh->tetra[1].v[1] = 2; mmgMesh->tetra[1].v[2] = 4; mmgMesh->tetra[1].v[3] = 8; mmgMesh->tetra[1].ref = 1; + mmgMesh->tetra[2].v[0] = 8; mmgMesh->tetra[2].v[1] = 3; mmgMesh->tetra[2].v[2] = 2; mmgMesh->tetra[2].v[3] = 7; mmgMesh->tetra[2].ref = 1; + mmgMesh->tetra[3].v[0] = 2; mmgMesh->tetra[3].v[1] = 5; mmgMesh->tetra[3].v[2] = 6; mmgMesh->tetra[3].v[3] = 8; mmgMesh->tetra[3].ref = 1; + mmgMesh->tetra[4].v[0] = 8; mmgMesh->tetra[4].v[1] = 5; mmgMesh->tetra[4].v[2] = 1; mmgMesh->tetra[4].v[3] = 2; mmgMesh->tetra[4].ref = 1; + mmgMesh->tetra[5].v[0] = 2; mmgMesh->tetra[5].v[1] = 7; mmgMesh->tetra[5].v[2] = 8; mmgMesh->tetra[5].v[3] = 6; mmgMesh->tetra[5].ref = 1; + mmgMesh->tetra[6].v[0] = 2; mmgMesh->tetra[6].v[1] = 4; mmgMesh->tetra[6].v[2] = 3; mmgMesh->tetra[6].v[3] = 8; mmgMesh->tetra[6].ref = 1; + mmgMesh->tetra[7].v[0] = 2; mmgMesh->tetra[7].v[1] = 9; mmgMesh->tetra[7].v[2] = 3; mmgMesh->tetra[7].v[3] = 7; mmgMesh->tetra[7].ref = 2; + mmgMesh->tetra[8].v[0] = 7; mmgMesh->tetra[8].v[1] = 11; mmgMesh->tetra[8].v[2] = 9; mmgMesh->tetra[8].v[3] = 12; mmgMesh->tetra[8].ref = 2; + mmgMesh->tetra[9].v[0] = 9; mmgMesh->tetra[9].v[1] = 6; mmgMesh->tetra[9].v[2] = 10; mmgMesh->tetra[9].v[3] = 7; mmgMesh->tetra[9].ref = 2; + mmgMesh->tetra[10].v[0] = 7; mmgMesh->tetra[10].v[1] = 6; mmgMesh->tetra[10].v[2] = 2; mmgMesh->tetra[10].v[3] = 9; mmgMesh->tetra[10].ref = 2; + mmgMesh->tetra[11].v[0] = 9; mmgMesh->tetra[11].v[1] = 12; mmgMesh->tetra[11].v[2] = 7; mmgMesh->tetra[11].v[3] = 10; mmgMesh->tetra[11].ref = 2; + mmgMesh->tetra[12].v[0] = 9; mmgMesh->tetra[12].v[1] = 3; mmgMesh->tetra[12].v[2] = 11; mmgMesh->tetra[12].v[3] = 7; mmgMesh->tetra[12].ref = 2; + + + /*metric*/ + mmgSol = (MMG_pSol)calloc(1,sizeof(MMG_Sol)); + assert(mmgSol); + mmgSol->offset = 1; + + /*scalaire size*/ + mmgSol->np = mmgMesh->np; + mmgSol->npmax = mmgMesh->npmax; + mmgSol->met = (double*)calloc(mmgSol->npmax+1,(int)mmgSol->offset*sizeof(double)); + assert(mmgSol->met); + mmgSol->metold = (double*)calloc(mmgSol->npmax+1,mmgSol->offset*sizeof(double)); + assert(mmgSol->metold); + for(k=1 ; k<=mmgMesh->np ; k++) { + mmgSol->met[k] = 0.5; + } + + opt[0]=4; //splitting + opt[1]=0; //debug + opt[2]=64; //par default 64 + opt[3]=0;//noswap + opt[4]=0;//noinsert + opt[5]=0;//nomove + opt[6]=5; //imprim + opt[7]=3; //renum + opt[8]=500; //renum + + if(MMG_mmg3dlib(opt,mmgMesh,mmgSol)) { + fprintf(stdout,"BAD ENDING OF MMG3DLIB\n"); + } + + /*save result*/ + MMG_saveMesh(mmgMesh,"result.mesh"); + + /*save metric*/ + MMG_saveSol(mmgMesh,mmgSol,"result.sol"); + + /* free mem */ + free(mmgMesh->point); + free(mmgMesh->disp->alpha); + free(mmgMesh->disp->mv); + free(mmgMesh->disp); + free(mmgMesh->tria); + free(mmgMesh->tetra); + free(mmgMesh); + if ( mmgSol->npfixe ) free(mmgSol->met); + free(mmgSol); + + + return(0); +} diff --git a/contrib/mmg3d/build/sources/analar.c b/contrib/mmg3d/build/sources/analar.c new file mode 100644 index 0000000000..ee4aa1e5bb --- /dev/null +++ b/contrib/mmg3d/build/sources/analar.c @@ -0,0 +1,357 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ + + + +#include "mesh.h" + +#define EPS4 1.e-04 + +extern int MMG_npuiss,MMG_nvol,MMG_npres; +extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex; +extern int MMG_npuisstot,MMG_nvoltot,MMG_nprestot; +extern int MMG_npdtot; + int MMG_nplen,MMG_npref,MMG_bouffe; + +int MMG_interp_ani(double *ma,double *mb,double *mp,double t) { + double dma[6],dmb[6],mai[6],mbi[6],mi[6]; + int i; + + for (i=0; i<6; i++) { + dma[i] = ma[i]; + dmb[i] = mb[i]; + } + if ( !MMG_invmat(dma,mai) || !MMG_invmat(dmb,mbi) ) { + fprintf(stderr," ## INTERP INVALID METRIC.\n"); + return(0); + } + for (i=0; i<6; i++) + mi[i] = (1.0-t)*mai[i] + t*mbi[i]; + + if ( !MMG_invmat(mi,mai) ) { + fprintf(stderr," ## INTERP INVALID METRIC.\n"); + return(0); + } + + for (i=0; i<6; i++) mp[i] = mai[i]; + + return(1); +} + +int MMG_interplog(double *ma,double *mb,double *mp,double *mplog,double t) { + double dma[6],dmb[6],mai[6],mi[6]; + int i,ii,jj,kk; + double lambda[3],v[3][3]; + + for (i=0; i<6; i++) { + dma[i] = ma[i]; + dmb[i] = mb[i]; + } + + for (i=0; i<6; i++) + mi[i] = (1.0-t)*dma[i] + t*dmb[i]; + + /*pour metrique log : extraction vp et exponentielle*/ + if ( !eigenv(1,mi,lambda,v) ) { + puts("pbs eigen interp"); + return(0); + } + for (i=0; i<3; i++) lambda[i] = exp(lambda[i]); + kk = 0; + for (ii=0; ii<3; ii++) { + for (jj=ii; jj<3; jj++) { + mai[kk] = lambda[0]*v[0][ii]*v[0][jj] + + lambda[1]*v[1][ii]*v[1][jj] + + lambda[2]*v[2][ii]*v[2][jj]; + kk = kk+1; + } + } + + /*if ( !MMG_invmat(mi,mai) ) { + fprintf(stderr," ## INTERP INVALID METRIC.\n"); + return(0); + } */ + + for (i=0; i<6; i++) mplog[i] = mi[i]; + for (i=0; i<6; i++) mp[i] = mai[i]; + + return(1); +} +int MMG_interp_iso(double *ma,double *mb,double *mp,double t) { + + *mp = (1.0-t)*(*ma) + t*(*mb); + return(1); +} +//#define LLONG 1.1 +//#define LSHORT 0.9 +/* optimisation based on edge lengths */ +int MMG_analar(pMesh mesh,pSol sol,pBucket bucket,int *na,int *nd,int *nf,int *alert) { + pTetra pt; + pPoint pa,pb; + List list; + double len,coef,siz,t1,declic,*ma,*mb,*mip,*ca,*cb,mp[6],c[3]; + //double *malog,*mblog,mplog[6]; + int i,k,lon,nad,ndd,npp,npd,ia,ib,ip,ipa,ipb,nedep,base,ifilt; + int *adja,adj,ret,vois[4],ref,tag,iadr,j,imax; + char tabar,tagedg; + int MMG_ncavity; + + /* for Delaunay cavity */ + if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) { + fprintf(stdout," ## MEMORY ALLOCATION PROBLEM.\n"); + return(0); + } + +MMG_npuiss=0; +MMG_npres=0; +MMG_nvol=0; +MMG_ncavity=0; +MMG_nplen=0; +MMG_npref=0; +MMG_nlen = 0; +MMG_ncal = 0; +MMG_ntopo = 0; +MMG_nex = 0; +MMG_bouffe = 0; + + npp = 0; + nad = 0; + ndd = 0; + npd = 0; + coef = QDEGRAD;//1.;//QDEGRAD; + ifilt = 0; + nedep = mesh->ne; + base = ++mesh->flag; + + declic = 1.5/ALPHAD;// 60.*LLONG; + + for (k=1; k<=nedep; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag != base-1 ) continue; + if ( pt->qual < declic ) continue; + pt->flag = base-2; + + /* mark internal edges */ + tabar = 0; + tagedg = 0; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + adj = vois[i]; + ref = mesh->tetra[adj].ref; + tag = mesh->tetra[adj].flag; + if ( !adj || pt->ref != ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + if ( adj && tag == base - 2 ) { + tagedg |= 1 << MMG_iarf[i][0]; + tagedg |= 1 << MMG_iarf[i][1]; + tagedg |= 1 << MMG_iarf[i][2]; + } + + } + if ( (tabar == ALL_BDRY) || (tagedg == ALL_BDRY) ) continue; + + //imax = ((int) pt->qual)%6; + imax = 0; + + for (j=imax; j<imax+6; j++) { + i = j; + if ( (tabar & 1<<i) || (tagedg & 1<<i) ) continue; + + /* edge length */ + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + + if ( len > LLONG && *alert != 1 ) { + npp++; + + siz=0.5; + + /* metric interpolation */ + if ( sol->offset==1 ) { + if(!MMG_interp(ma,mb,mp,siz) ) continue; + } + else { + iadr = (ipa-1)*sol->offset + 1; + //malog = &sol->metold[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + //mblog = &sol->metold[iadr]; + //if ( !MMG_interplog(malog,mblog,mp,mplog,siz) ) continue; + if ( !MMG_interp_ani(ma,mb,mp,siz) ) continue; + } + + t1 = 1.0 - siz; + c[0] = t1*ca[0] + siz*cb[0]; + c[1] = t1*ca[1] + siz*cb[1]; + c[2] = t1*ca[2] + siz*cb[2]; + //printf("siz %e new len %e - %e (%e) %d %d\n", siz,MMG_length(ca,c,ma,mb),MMG_length(cb,c,ma,mb),len,(int)(len+0.5),nbp); + ip = MMG_newPt(mesh,c); + if ( ip < 1 ) { + *alert = 1; + break; + } + else { + iadr = (ip-1)*sol->offset + 1; + //mipold = &sol->metold[iadr]; + //memcpy(mipold,mplog,sol->offset*sizeof(double)); + mip = &sol->met[iadr]; + memcpy(mip,mp,sol->offset*sizeof(double)); + + /* bucket filter */ + if (!MMG_buckin(mesh,sol,bucket,ip) ) { + MMG_delPt(mesh,ip); + ifilt++; + continue; + } + + /* Delaunay kernel */ + lon = MMG_coquil(mesh,k,i,&list); + lon = MMG_cavity(mesh,sol,k,ip,&list,lon); + if ( lon < 1 ) { + MMG_delPt(mesh,ip); + npd++; + if ( lon == -1 ) { + MMG_ncavity++; + //printf("cavity pete\n"); + *alert = 2; + } else if ( lon < 0 ) { + *alert = 1; + break; + } + else { + continue; + } + } + else { + ret = MMG_delone(mesh,sol,ip,&list,lon); + if ( ret > 0 ) { + MMG_addBucket(mesh,bucket,ip); + nad++; + *alert = 0; + } + else if ( ret == 0 ) { + MMG_delPt(mesh,ip); + npd++; + *alert = 1; + break; + } + else { + MMG_delPt(mesh,ip); + npd++; + MMG_bouffe++; + } + } + } + break; + } + + else if ( len < LSHORT ) { + npp++; + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( MMG_colpoi(mesh,sol,k,ia,ib,coef) ) { + MMG_delBucket(mesh,bucket,ipb); + MMG_delPt(mesh,ipb); + ndd++; + break; + } + else if ( MMG_colpoi(mesh,sol,k,ib,ia,coef) ) { + MMG_delBucket(mesh,bucket,ipa); + MMG_delPt(mesh,ipa); + ndd++; + break; + } + } + } + if ( *alert == 1 ) break; + } + + *na = nad; + *nd = ndd; + *nf += ifilt; + if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) { + printf("analyzed %d \n",npp); + printf("rejected colpoi : cal %d , len %d , topo %d , ex %d\n",MMG_ncal,MMG_nlen,MMG_ntopo,MMG_nex); + MMG_npdtot+=npd; + MMG_nvoltot+=MMG_nvol; + MMG_npuisstot+=MMG_npuiss; + MMG_nprestot+=MMG_npres; + if (npd>0) { + printf("rejected %d : cavity %d vol %d , puiss %d , pres %d bouffe %d\n",npd,MMG_ncavity,MMG_nvol,MMG_npuiss,MMG_npres,MMG_bouffe); + } + } + + if ( *alert == 1 ) { + fprintf(stdout," ## UNABLE TO CREATE NEW ELEMENT %d , %d\n", + mesh->np,mesh->ne); + } else *alert = 0; + M_free(list.hedg.item); + return(1); +} + + diff --git a/contrib/mmg3d/build/sources/analarcutting.c b/contrib/mmg3d/build/sources/analarcutting.c new file mode 100644 index 0000000000..e36ca14134 --- /dev/null +++ b/contrib/mmg3d/build/sources/analarcutting.c @@ -0,0 +1,319 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + + +//#define LLLONG 3.//2.5 + +int MMG_permar[12][4] = {{0,1,2,3},{0,2,3,1},{2,0,1,3},{0,3,1,2},{1,0,3,2},{3,2,1,0}, + {3,0,2,1},{1,2,0,3}, + {3,1,0,2},{2,3,0,1},{2,1,3,0},{1,3,2,0}}; + +int MMG_pointar[64][2] = {{-1,-1}, + {0,1}, + {2,1}, + {4,22}, + {6,1}, + {6,22}, + {2,22}, + {10,31}, + {7,1}, + {10,22}, + {1,22}, + {10,3}, + {0,2}, + {11,33}, + {4,32}, + {4,4}, + {8,1}, + {0,22}, + {7,2}, + {10,32}, + {11,22}, + {0,3}, + {0,33}, + {6,4}, + {8,22}, + {9,31}, + {4,33}, + {10,4}, + {0,32}, + {0,4}, + {2,41}, + {9,5}, + {9,1}, + {2,2}, + {5,22}, + {10,33}, + {3,22}, + {2,32}, + {2,3}, + {2,4}, + {7,22}, + {1,32}, + {3,31}, + {1,4}, + {2,33}, + {7,41}, + {5,4}, + {11,5}, + {9,22}, + {6,33}, + {7,32}, + {0,41}, + {0,31}, + {11,4}, + {3,4}, + {7,5}, + {7,3}, + {8,4}, + {7,4}, + {3,5}, + {9,4}, + {1,5}, + {0,5}, + {0,6} + }; + +int MMG_createPoint(pMesh mesh, pSol sol, int ipa, int ipb) { + double *ca,*cb,*ma,*mb,*mip,mp[6],*mipold,mplog[6],c[3]; + //double *malog,*mblog; + int iadr,ip; + + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + c[0] = 0.5*(ca[0] + cb[0]); + c[1] = 0.5*(ca[1] + cb[1]); + c[2] = 0.5*(ca[2] + cb[2]); + + + ip = MMG_newPt(mesh,c); + + /* metric interpolation */ + if ( sol->offset==1 ) { + if ( !MMG_interp(ma,mb,mp,0.5) ) return(0); + } + else { + iadr = (ipa-1)*sol->offset + 1; + //malog = &sol->metold[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + //mblog = &sol->metold[iadr]; + //if ( !MMG_interplog(malog,mblog,mp,mplog,0.5) ) return(0); + if ( !MMG_interp_ani(ma,mb,mp,0.5) ) return(0); + } + iadr = (ip-1)*sol->offset + 1; + mipold = &sol->metold[iadr]; + memcpy(mipold,mplog,sol->offset*sizeof(double)); + mip = &sol->met[iadr]; + memcpy(mip,mp,sol->offset*sizeof(double)); + + return(ip); +} + +extern int ddebug; +int MMG_analarcutting(pMesh mesh,pSol sol,pHedge hash,int *alert,double* lmoy,double LLLONG) { + pTetra pt; + int k,i,ia,ib,ip,ipa,ipb,iadr,na,ncut; + double *ca,*cb,len,*ma,*mb; + int nb[7],ne,base; + int ned; + int n1,n2,n3,n4,n5,n6,n22,n31,n32,n33,n41; + + n1 = n2 = n3 = n4 = n5 = n6 = n22 = n31 = n32 = n33 = n41 = 0; + na = 0; + *alert = 0; + ne = mesh->ne; + base = ++mesh->flag; + + ned = 0; + *lmoy = 0; + for (k=1; k<=ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag == base ) continue; //attention si Delaunay avant on peut avoir des trous dans le tab des tets... + //normalement on devrait pouvoir juste traiter les tets à base-1... non ? + pt->tabedg = 0; //because used by cendel + assert(!pt->tabedg); + + ncut = 0; + for (i=0; i<6; i++) { + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + /* already cutted ? */ + nb[i] = MMG_edgePoint(hash,ipa,ipb); + if ( nb[i] ) { + //if(nb[i]==6992) printf("already cut %d %d : %d -- %d\n",ipa,ipb,nb[i],k); + pt->tabedg |= 1 << i; + ncut++; + continue; + } + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + /* edge length */ + len = MMG_length(ca,cb,ma,mb); + *lmoy += len; + ned++; + if ( len > LLLONG ) { + ip = MMG_createPoint(mesh,sol,ipa,ipb); + //if(ip==6992) printf("on cree %d : %d -- %d %d %d %d\n",ip,k,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + if ( !ip ) { + *alert = 1; + return(0); + } + /*hash insertion*/ + if ( !MMG_edgePut(hash,ipa,ipb,ip) ) { + printf("ahhhhhhhhhhhhhhhhh %d %d\n",ipa,ipb); + exit(0); + } + nb[i] = ip; + pt->tabedg |= 1 << i; + na++; + ncut++; + } + } + //if(if(mesh->info.ddebug)) printf("tet %d ncut %d : %d %d\n",k,ncut,pt->tabedg,MMG_pointar[pt->tabedg][1]); + //if(ddebug && ncut) printf("tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + if (!ncut) continue; + else if ( MMG_pointar[pt->tabedg][1] > -1 ) { + if(mesh->info.ddebug){ + printf("tet %d : %d\n",k,MMG_pointar[pt->tabedg][1]); + printf("pour ce tet ref : %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + } + switch(MMG_pointar[pt->tabedg][1]) { + case 1: + n1++; + MMG_pattern1(mesh,sol,hash,k); + break; + case 2: + n2++; + MMG_pattern2(mesh,sol,hash,k); + break; + case 3: + n3++; + MMG_pattern3(mesh,sol,hash,k); + break; + case 4: + MMG_pattern4(mesh,sol,hash,k); + n4++; + break; + case 5: + MMG_pattern5(mesh,sol,hash,k); + n5++; + break; + case -1: + puts("MMG_analar case -1"); + exit(0); + case 6: + MMG_pattern6(mesh,sol,k,nb); + n6++; + break; + case 22: + MMG_pattern22(mesh,sol,hash,k); + n22++; + break; + case 31: + MMG_pattern31(mesh,sol,hash,k); + n31++; + break; + case 32: + MMG_pattern32(mesh,sol,hash,k); + n32++; + break; + case 33: + MMG_pattern33(mesh,sol,hash,k); + n33++; + break; + case 41: + MMG_pattern41(mesh,sol,hash,k); + n41++; + break; + + } + // if ( 1 ){printf("pointar tet 6545 : %d %d %d %d %d\n", + // MMG_pointar[pt->tabedg][1],mesh->tetra[6545].v[0],mesh->tetra[6545].v[1] + // ,mesh->tetra[6545].v[2],mesh->tetra[6545].v[3]); + // printf("bdry ref : %d %d %d %d\n",mesh->tetra[6545].bdryref[0],mesh->tetra[6545].bdryref[1] + // ,mesh->tetra[6545].bdryref[2],mesh->tetra[6545].bdryref[3]);} + //if(mesh->ne>=41495) {exit(0); } + + }/*end if pointar > -1*/ + } + *lmoy /= ned; + + /*puts("stats cut -------------------"); + printf("1 cut : %8d\n",n1); + printf("2 cut : %8d %8d\n",n2,n22); + printf("3 cut : %8d %8d %8d %8d\n",n3,n31,n32,n33); + printf("4 cut : %8d %8d\n",n4,n41); + printf("5 cut : %8d\n",n5); + printf("6 cut : %8d\n",n6); + printf("---------------------------\n"); */ + if ( !na ) return(na); +#warning check memory allocation + + //printf("%d cut init --- nb tet %d\n",na,mesh->ne); + return(na); +} + + + + + diff --git a/contrib/mmg3d/build/sources/baryct.c b/contrib/mmg3d/build/sources/baryct.c new file mode 100644 index 0000000000..138f158f9e --- /dev/null +++ b/contrib/mmg3d/build/sources/baryct.c @@ -0,0 +1,112 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define EPST -1.e-14 +#define EPSR 1.e+14 + + +/* compute barycentrics */ +int MMG_baryct(pMesh mesh,pTetra pt,double p[3],double cb[4]) { + pPoint p0,p1,p2,p3; + double bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz; + double epsra,vol1,vol2,vol3,vol4,dd; + + p0 = &mesh->point[pt->v[0]]; + p1 = &mesh->point[pt->v[1]]; + p2 = &mesh->point[pt->v[2]]; + p3 = &mesh->point[pt->v[3]]; + + /* barycentric */ + bx = p1->c[0] - p0->c[0]; + by = p1->c[1] - p0->c[1]; + bz = p1->c[2] - p0->c[2]; + cx = p2->c[0] - p0->c[0]; + cy = p2->c[1] - p0->c[1]; + cz = p2->c[2] - p0->c[2]; + dx = p3->c[0] - p0->c[0]; + dy = p3->c[1] - p0->c[1]; + dz = p3->c[2] - p0->c[2]; + + /* test volume */ + vx = cy*dz - cz*dy; + vy = cz*dx - cx*dz; + vz = cx*dy - cy*dx; + + epsra = EPST*(bx*vx + by*vy + bz*vz); + apx = p[0] - p0->c[0]; + apy = p[1] - p0->c[1]; + apz = p[2] - p0->c[2]; + + /* p in 2 */ + vol2 = apx*vx + apy*vy + apz*vz; + if ( epsra > vol2 ) return(0); + + /* p in 3 */ + vx = by*apz - bz*apy; + vy = bz*apx - bx*apz; + vz = bx*apy - by*apx; + vol3 = dx*vx + dy*vy + dz*vz; + if ( epsra > vol3 ) return(0); + + /* p in 4 */ + vol4 = -cx*vx - cy*vy - cz*vz; + if ( epsra > vol4 ) return(0); + + /* p in 1 */ + vol1 = -epsra * EPSR - vol2 - vol3 - vol4; + if ( epsra > vol1 ) return(0); + + dd = vol1+vol2+vol3+vol4; + if ( dd != 0.0 ) dd = 1.0 / dd; + cb[0] = vol1 * dd; + cb[1] = vol2 * dd; + cb[2] = vol3 * dd; + cb[3] = vol4 * dd; + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/boulep.c b/contrib/mmg3d/build/sources/boulep.c new file mode 100644 index 0000000000..001bd54e92 --- /dev/null +++ b/contrib/mmg3d/build/sources/boulep.c @@ -0,0 +1,206 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + + +/* find all tets sharing P + in: start : tetrahedron containing p + ip : index of p in start + list : dynamic list structure (allocated outside) + out: list : list of tets */ +int MMG_boulep(pMesh mesh,int start,int ip,pList list) { + pTetra pt,pt1; + pPoint ppt; + int *adja,adj,i,j,indp,iel,iadr,base,ilist,nump; + int vois[4]; + + if ( start < 1 ) return(0); + pt = &mesh->tetra[start]; + if ( !pt->v[0] ) return(0); + nump = pt->v[ip]; + ppt = &mesh->point[nump]; + if ( ppt->tag & M_BDRY || ppt->tag & M_UNUSED ) return(0); + + /* store initial tet */ + base = ++mesh->mark; + pt->mark = base; + ilist = 1; + list->tetra[ilist] = 4*start + ip; + + /* store 3 neighbors sharing P */ + iadr = (start-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + if ( i == ip ) continue; + adj = vois[i]; + if ( adj ) { + pt1 = &mesh->tetra[adj]; + if ( pt1->mark != base ) { + pt1->mark = base; + for (j=0; j<4; j++) + if ( pt1->v[j] == nump ) break; + ilist++; + list->tetra[ilist] = 4*adj + j; + } + } + } + if ( ilist < 2 ) return(ilist); + + /* explore list of neighbors */ + indp = 2; + do { + iel = list->tetra[indp] >> 2; + pt = &mesh->tetra[iel]; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + + for (i=0; i<4; i++) { + if ( pt->v[i] == nump ) continue; + adj = vois[i]; + if ( adj ) { + pt1 = &mesh->tetra[adj]; + if ( pt1->mark != base ) { + pt1->mark = base; + for (j=0; j<4; j++) + if ( pt1->v[j] == nump ) break; + ilist++; + list->tetra[ilist] = 4*adj + j; + } + } + } + /* overflow */ + if ( ilist > LONMAX-3 ) return(-ilist); + } + while ( ++indp <= ilist ); + + return(ilist); +} + + +/* idem boulep for any vertex */ +int MMG_bouleg(pMesh mesh,int start,int ip,pList list) { + pTetra pt,pt1; + pPoint ppt; + int *adja,adj,i,j,indp,iel,iadr,base,ilist,nump; + int vois[4]; + + if ( start < 1 ) return(0); + pt = &mesh->tetra[start]; + if ( !pt->v[0] ) return(0); + nump = pt->v[ip]; + ppt = &mesh->point[nump]; + if ( ppt->tag & M_UNUSED ) return(0); + + /* store initial tet */ + base = ++mesh->mark; + pt->mark = base; + ilist = 1; + list->tetra[ilist] = 4*start + ip; + + /* store 3 neighbors sharing P */ + iadr = (start-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + if ( i == ip ) continue; + adj = vois[i]; + if ( adj ) { + pt1 = &mesh->tetra[adj]; + if ( pt1->mark != base ) { + pt1->mark = base; + for (j=0; j<4; j++) + if ( pt1->v[j] == nump ) break; + ilist++; + list->tetra[ilist] = 4*adj + j; + } + } + } + if ( ilist < 2 ) return(ilist); + + /* explore list of neighbors */ + indp = 2; + do { + iel = list->tetra[indp] >> 2; + pt = &mesh->tetra[iel]; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + + for (i=0; i<4; i++) { + if ( pt->v[i] == nump ) continue; + adj = vois[i]; + if ( adj ) { + pt1 = &mesh->tetra[adj]; + if ( pt1->mark != base ) { + pt1->mark = base; + for (j=0; j<4; j++) + if ( pt1->v[j] == nump ) break; + ilist++; + list->tetra[ilist] = 4*adj + j; + } + } + } + /* overflow */ + if ( ilist > LONMAX-3 ) return(-ilist); + } + while ( ++indp <= ilist ); + + return(ilist); +} diff --git a/contrib/mmg3d/build/sources/bucket.c b/contrib/mmg3d/build/sources/bucket.c new file mode 100644 index 0000000000..7b8938b8db --- /dev/null +++ b/contrib/mmg3d/build/sources/bucket.c @@ -0,0 +1,385 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* create bucket structure and store initial vertices */ +pBucket MMG_newBucket(pMesh mesh,int nmax) { + pPoint ppt; + pBucket bucket; + double dd; + int k,ic,ii,jj,kk; + + /* memory alloc */ + bucket = (Bucket*)M_malloc(sizeof(Bucket),"newBucket"); + assert(bucket); + bucket->size = nmax; + bucket->head = (int*)M_calloc(nmax*nmax*nmax+1,sizeof(int),"newBucket.head"); + assert(bucket->head); + bucket->link = (int*)M_calloc(mesh->npmax+1,sizeof(int),"newBucket.link"); + assert(bucket->link); + + /* insert vertices */ + dd = nmax / (double)PRECI; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ii = M_MAX(0,(int)(dd * ppt->c[0])-1); + jj = M_MAX(0,(int)(dd * ppt->c[1])-1); + kk = M_MAX(0,(int)(dd * ppt->c[2])-1); + ic = (kk*nmax + jj)*nmax + ii; + + if ( !bucket->head[ic] ) + bucket->head[ic] = k; + else { + bucket->link[k] = bucket->head[ic]; + bucket->head[ic] = k; + } + } + + return(bucket); +} + + +void MMG_freeBucket(pBucket bucket) { + M_free(bucket->head); + M_free(bucket->link); + M_free(bucket); +} + + +/* check and eventually insert vertex */ +int MMG_buckin_ani(pMesh mesh,pSol sol,pBucket bucket,int ip) { + pPoint ppt,pp1; + double dd,d2,det,ux,uy,uz,dmi,m1,m2,m3,dx,dy,dz; + double *ma,*mb; + int i,j,k,ii,jj,kk,ic,icc,siz,ip1; + int iadr,imin,imax,jmin,jmax,kmin,kmax; + + ppt = &mesh->point[ip]; + siz = bucket->size; + dd = siz / (double)PRECI; + + iadr = (ip-1)*sol->offset + 1; + ma = &sol->met[iadr]; + dmi = LFILT*LFILT; + + ii = M_MAX(0,(int)(dd * ppt->c[0])-1); + jj = M_MAX(0,(int)(dd * ppt->c[1])-1); + kk = M_MAX(0,(int)(dd * ppt->c[2])-1); + ic = (kk*siz + jj)*siz + ii; + + /* check current cell */ + if ( bucket->head[ic] ) { + ip1 = bucket->head[ic]; + pp1 = &mesh->point[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \ + + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz); + if ( d2 < dmi ) { + iadr = (ip1-1)*sol->offset + 1; + mb = &sol->met[iadr]; + d2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + if ( d2 < dmi ) return(0); + } + + while ( bucket->link[ip1] ) { + ip1 = bucket->link[ip1]; + pp1 = &mesh->point[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \ + + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz); + if ( d2 < dmi ) { + iadr = (ip1-1)*sol->offset + 1; + mb = &sol->met[iadr]; + d2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + if ( d2 < dmi ) return(0); + } + } + } + + /* bounding box */ + det = ma[0] * (ma[3]*ma[5] - ma[4]*ma[4]) \ + - ma[1] * (ma[1]*ma[5] - ma[2]*ma[4]) \ + + ma[2] * (ma[1]*ma[4] - ma[3]*ma[2]); + det = 1.0 / det; + m1 = ma[3]*ma[5] - ma[4]*ma[4]; + m2 = ma[0]*ma[5] - ma[2]*ma[2]; + m3 = ma[0]*ma[3] - ma[1]*ma[1]; + if ( det < 0.0 || m1 < 0.0 ) + return(1); + else { + dx = LFILT * sqrt(m1 * det) ; + dy = LFILT * sqrt(m2 * det) ; + dz = LFILT * sqrt(m3 * det) ; + } + + imin = (int)(dd * (ppt->c[0]-dx))-1; + jmin = (int)(dd * (ppt->c[1]-dy))-1; + kmin = (int)(dd * (ppt->c[2]-dz))-1; + imax = (int)(dd * (ppt->c[0]+dx))-1; + jmax = (int)(dd * (ppt->c[1]+dy))-1; + kmax = (int)(dd * (ppt->c[2]+dz))-1; + + imin = M_MAX(0,M_MIN(imin,siz-1)); + imax = M_MIN(siz-1,M_MAX(0,imax)); + jmin = M_MAX(0,M_MIN(jmin,siz-1)); + jmax = M_MIN(siz-1,M_MAX(0,jmax)); + kmin = M_MAX(0,M_MIN(kmin,siz-1)); + kmax = M_MIN(siz-1,M_MAX(0,kmax)); + if ( imin == imax && jmin == jmax && kmin == kmax ) return(1); + + /* explore neighbours */ + for (k=kmin; k<=kmax; k++) + for (j=jmin; j<=jmax; j++) + for (i=imin; i<=imax; i++) { + icc = (k*siz + j)*siz + i; + ip1 = bucket->head[icc]; + if ( !ip1 ) continue; + pp1 = &mesh->point[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \ + + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz); + if ( d2 < dmi ) { + iadr = (ip1-1)*sol->offset + 1; + mb = &sol->met[iadr]; + d2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + if ( d2 < dmi ) return(0); + } + + while ( bucket->link[ip1] ) { + ip1 = bucket->link[ip1]; + pp1 = &mesh->point[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \ + + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz); + if ( d2 < dmi ) { + iadr = (ip1-1)*sol->offset + 1; + mb = &sol->met[iadr]; + d2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + if ( d2 < dmi ) return(0); + } + } + } + + return(1); +} + + +int MMG_buckin_iso(pMesh mesh,pSol sol,pBucket bucket,int ip) { + pPoint ppt,pp1; + double dd,d2,ux,uy,uz,hpi,hp1,hp2; + int i,j,k,ii,jj,kk,ic,icc,siz,ip1; + int imin,imax,jmin,jmax,kmin,kmax; + + ppt = &mesh->point[ip]; + siz = bucket->size; + dd = siz / (double)PRECI; + hpi = LFILT * sol->met[ip]; + hp1 = hpi*hpi; + + ii = M_MAX(0,(int)(dd * ppt->c[0])-1); + jj = M_MAX(0,(int)(dd * ppt->c[1])-1); + kk = M_MAX(0,(int)(dd * ppt->c[2])-1); + ic = (kk*siz + jj)*siz + ii; + + /* check current cell */ + if ( bucket->head[ic] ) { + ip1 = bucket->head[ic]; + pp1 = &mesh->point[ip1]; + hp2 = LFILT * sol->met[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ux*ux + uy*uy + uz*uz; + if ( d2 < hp1 || d2 < hp2*hp2 ) { +//printf("filtre current %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2); + return(0); + } + + while ( bucket->link[ip1] ) { + ip1 = bucket->link[ip1]; + pp1 = &mesh->point[ip1]; + hp2 = LFILT * sol->met[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ux*ux + uy*uy + uz*uz; + if ( d2 < hp1 || d2 < hp2*hp2 ) { +//printf("filtre link %d : %e %e %e %e\n",ip1,d2,hp1,d2,hp2*hp2); + return(0); + } + } + } + + /* explore neighbors */ + imin = (int)(dd * (ppt->c[0]-hpi))-1; + jmin = (int)(dd * (ppt->c[1]-hpi))-1; + kmin = (int)(dd * (ppt->c[2]-hpi))-1; + imax = (int)(dd * (ppt->c[0]+hpi))-1; + jmax = (int)(dd * (ppt->c[1]+hpi))-1; + kmax = (int)(dd * (ppt->c[2]+hpi))-1; + + imin = M_MAX(0,M_MIN(imin,siz-1)); + imax = M_MIN(siz-1,M_MAX(0,imax)); + jmin = M_MAX(0,M_MIN(jmin,siz-1)); + jmax = M_MIN(siz-1,M_MAX(0,jmax)); + kmin = M_MAX(0,M_MIN(kmin,siz-1)); + kmax = M_MIN(siz-1,M_MAX(0,kmax)); + if ( imin == imax && jmin == jmax && kmin == kmax ) return(1); + + for (k=kmin; k<=kmax; k++) + for (j=jmin; j<=jmax; j++) + for (i=imin; i<=imax; i++) { + icc = (k*siz + j)*siz + i; + ip1 = bucket->head[icc]; + if ( !ip1 ) continue; + pp1 = &mesh->point[ip1]; + hp2 = LFILT * sol->met[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ux*ux + uy*uy + uz*uz; + if ( d2 < hp1 || d2 < hp2*hp2 ) { +/* printf("other cell %d %e < %e -- %e < %e \n",ip1,d2,MMG_length(mesh,sol,ip,ip1),d2,hp2*hp2); + printf("on filtre avec %d : %e %e %e\n",ip1,pp1->c[0],pp1->c[1],pp1->c[2]); + */ return(0); + } + + while ( bucket->link[ip1] ) { + ip1 = bucket->link[ip1]; + pp1 = &mesh->point[ip1]; + hp2 = LFILT * sol->met[ip1]; + ux = pp1->c[0] - ppt->c[0]; + uy = pp1->c[1] - ppt->c[1]; + uz = pp1->c[2] - ppt->c[2]; + d2 = ux*ux + uy*uy + uz*uz; + if ( d2 < hp1 || d2 < hp2*hp2 ) { +// printf("link cell %d %e < %e -- %e < %e \n",ip1,d2,hp1,d2,hp2*hp2); + return(0); + } + } + } + + return(1); +} + + +int MMG_addBucket(pMesh mesh,pBucket bucket,int ip) { + pPoint ppt; + double dd; + int ic,ii,jj,kk,siz; + + ppt = &mesh->point[ip]; + siz = bucket->size; + dd = siz / (double)PRECI; + + ii = M_MAX(0,(int)(dd * ppt->c[0])-1); + jj = M_MAX(0,(int)(dd * ppt->c[1])-1); + kk = M_MAX(0,(int)(dd * ppt->c[2])-1); + ic = (kk*siz + jj)*siz + ii; + + /* store new point */ + if ( !bucket->head[ic] ) { + bucket->head[ic] = ip; + bucket->link[ip] = 0; + } + else { + bucket->link[ip] = bucket->head[ic]; + bucket->head[ic] = ip; + assert(ip!=bucket->link[ip]); + } + + return(1); +} + + +int MMG_delBucket(pMesh mesh,pBucket bucket,int ip) { + pPoint ppt; + double dd; + int ic,ii,jj,kk,siz,ip1; + + ppt = &mesh->point[ip]; + siz = bucket->size; + dd = siz / (double)PRECI; + + ii = M_MAX(0,(int)(dd * ppt->c[0])-1); + jj = M_MAX(0,(int)(dd * ppt->c[1])-1); + kk = M_MAX(0,(int)(dd * ppt->c[2])-1); + ic = (kk*siz + jj)*siz + ii; + + /* remove vertex from cell */ + if ( bucket->head[ic] ) { + if ( bucket->head[ic] == ip ) { + bucket->head[ic] = bucket->link[ip]; + bucket->link[ip] = 0; + } + else { + ip1 = bucket->head[ic]; + while ( ip1 && bucket->link[ip1] != ip ) { + ip1 = bucket->link[ip1]; + } + if ( bucket->link[ip1] == ip ) { + bucket->link[ip1] = bucket->link[ip]; + bucket->link[ip] = 0; + } + } + } + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/cendel.c b/contrib/mmg3d/build/sources/cendel.c new file mode 100644 index 0000000000..41eab921bb --- /dev/null +++ b/contrib/mmg3d/build/sources/cendel.c @@ -0,0 +1,222 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define SCRIT 0.95 + + +int MMG_cendel(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pQueue queue; + List list; + double crit; + int *adja,adj,iadr,ier,i,j,k,jel,lon,ns,np; + int vois[4],ref,tag; + char tabar,done; + + /* queue on quality */ + queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1); + assert(queue); + + ns = np = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + np++; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag < base - 1) continue; + else if ( pt->qual < declic ) continue; + + /* mark internal edges */ + tabar = 0; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + adj = vois[i]; + ref = mesh->tetra[adj].ref; + tag = mesh->tetra[adj].flag; + if ( !adj || pt->ref != ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + } + if ( (tabar == ALL_BDRY) ) continue; + + /* swap for anisotropy */ + done = 0; + for (i=0; i<6; i++) { + if ( (tabar & 1<<i) ) continue; + + lon = MMG_coquil(mesh,k,i,&list); + if ( lon < 3 || lon > 7 ) continue; + + /* qual crit */ + crit = pt->qual; + for (j=2; j<=lon; j++) { + jel = list.tetra[j] / 6; + pt1 = &mesh->tetra[jel]; + crit = M_MAX(crit,pt1->qual); + } + crit *= SCRIT; + + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if ( ier > 0 ) { + ns++; + break; + } + else if ( ier < 0 ) { + fprintf(stdout," %7d PROPOSED %7d SWAPPED\n",np,ns); + fprintf(stdout," ## UNABLE TO SWAP.\n"); + MMG_kiufree(queue); + return(-ns); + } + } + } + while ( k ); + + if ( mesh->info.imprim < - 4 ) + fprintf(stdout," %7d PROPOSED %7d SWAPPED\n",np,ns); + + MMG_kiufree(queue); + return(ns); +} + +int MMG_cendellong(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pQueue queue; + List list; + double crit,cal; + int *adja,adj,iadr,ier,i,j,k,jel,lon,ns,np; + int vois[4],ref,tag; + char tabar,done; + int imin,jj; + /* queue on quality */ + queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1); + assert(queue); + + ns = np = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + np++; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag < base - 1) continue; + else if ( pt->qual < declic ) continue; + + /* mark internal edges */ + tabar = 0; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + adj = vois[i]; + ref = mesh->tetra[adj].ref; + tag = mesh->tetra[adj].flag; + if ( !adj || pt->ref != ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + } + if ( (tabar == ALL_BDRY) ) continue; + + /* swap for anisotropy */ + done = 0; + imin = ((int) pt->qual)%6; + for (jj=imin; jj<imin+6; jj++) { + i=jj%6; + if ( (tabar & 1<<i) ) continue; + + lon = MMG_coquil(mesh,k,i,&list); + if ( lon < 3 || lon > 7 ) continue; + //printf("on essaie de swapper %d\n",k); + + /* qual crit */ + crit = ( sol->offset==6 ) ? MMG_caltet_ani(mesh,sol,k):MMG_caltet_iso(mesh,sol,k) ; //pt->qual; + for (j=2; j<=lon; j++) { + jel = list.tetra[j] / 6; + pt1 = &mesh->tetra[jel]; + cal = ( sol->offset==6 ) ? MMG_caltet_ani(mesh,sol,jel):MMG_caltet_iso(mesh,sol,jel) ; + crit = M_MAX(crit,cal); + } + crit *= SCRIT; + //printf("$$$$$$$$$$$$$ crit %e %e\n",crit,crit/60.); + + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + //printf("swap ? %d\n",ier); + if ( ier > 0 ) { + ns++; + break; + } + else if ( ier < 0 ) { + fprintf(stdout," %7d PROPOSED %7d SWAPPED\n",np,ns); + fprintf(stdout," ## UNABLE TO SWAP.\n"); + MMG_kiufree(queue); + return(-ns); + } + } + } + while ( k ); + + if ( mesh->info.imprim < - 4 ) + fprintf(stdout," %7d PROPOSED %7d SWAPPED\n",np,ns); + + MMG_kiufree(queue); + return(ns); +} + diff --git a/contrib/mmg3d/build/sources/cenrad.c b/contrib/mmg3d/build/sources/cenrad.c new file mode 100644 index 0000000000..3a3921eaaa --- /dev/null +++ b/contrib/mmg3d/build/sources/cenrad.c @@ -0,0 +1,182 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* compute circumradius and center */ +int MMG_cenrad_iso(pMesh mesh,double *ct,double *c,double *rad) { + double dd,ux,uy,uz,n1[3],n2[3],n3[3],*c1,*c2,*c3,*c4,pl1,pl2,pl3; + double cc1,cc2,cc3; + + c1 = &ct[0]; + c2 = &ct[3]; + c3 = &ct[6]; + c4 = &ct[9]; + + ux = c4[0] - c1[0]; + uy = c4[1] - c1[1]; + uz = c4[2] - c1[2]; + dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + n1[0] = ux*dd; + n1[1] = uy*dd; + n1[2] = uz*dd; + + /* plan: vecteur directeur passant par milieu(1,4) */ + pl1 = n1[0]*(c4[0]+c1[0]) \ + + n1[1]*(c4[1]+c1[1]) + n1[2]*(c4[2]+c1[2]); + + ux = c4[0] - c2[0]; + uy = c4[1] - c2[1]; + uz = c4[2] - c2[2]; + dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + n2[0] = ux*dd; + n2[1] = uy*dd; + n2[2] = uz*dd; + pl2 = n2[0]*(c4[0]+c2[0]) \ + + n2[1]*(c4[1]+c2[1]) + n2[2]*(c4[2]+c2[2]); + + ux = c4[0] - c3[0]; + uy = c4[1] - c3[1]; + uz = c4[2] - c3[2]; + dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + n3[0] = ux*dd; + n3[1] = uy*dd; + n3[2] = uz*dd; + pl3 = n3[0]*(c4[0]+c3[0]) \ + + n3[1]*(c4[1]+c3[1]) + n3[2]*(c4[2]+c3[2]); + + /* center = intersection of 3 planes */ + ux = n2[1]*n3[2] - n2[2]*n3[1]; + uy = n1[2]*n3[1] - n1[1]*n3[2]; + uz = n1[1]*n2[2] - n1[2]*n2[1]; + + dd = n1[0]*ux + n2[0]*uy + n3[0]*uz; + dd = 0.5 / dd; + + cc1 = ux*pl1 + uy*pl2 + uz*pl3; + cc2 = pl1 * (n2[2]*n3[0] - n2[0]*n3[2]) \ + + pl2 * (n1[0]*n3[2] - n3[0]*n1[2]) \ + + pl3 * (n2[0]*n1[2] - n2[2]*n1[0]); + cc3 = pl1 * (n2[0]*n3[1] - n2[1]*n3[0]) \ + + pl2 * (n3[0]*n1[1] - n3[1]*n1[0]) \ + + pl3 * (n1[0]*n2[1] - n2[0]*n1[1]); + + c[0] = dd * cc1; + c[1] = dd * cc2; + c[2] = dd * cc3; + + /* radius (squared) */ + *rad = (c[0] - c4[0]) * (c[0] - c4[0]) \ + + (c[1] - c4[1]) * (c[1] - c4[1]) \ + + (c[2] - c4[2]) * (c[2] - c4[2]); + + return(1); +} + + +int MMG_cenrad_ani(pMesh mesh,double *ct,double *m,double *c,double *rad) { + double d1,d2,d3,det,dd,ux,uy,uz,vx,vy,vz,wx,wy,wz; + double ax,ay,az,bx,by,bz,cx,cy,cz; + + + dd = m[0]*ct[0]*ct[0] + m[3]*ct[1]*ct[1] + m[5]*ct[2]*ct[2] \ + + 2.0*(m[1]*ct[0]*ct[1] + m[2]*ct[0]*ct[2] + m[4]*ct[1]*ct[2]); + + /* MMG_lengths */ + d1 = m[0]*ct[3]*ct[3] + m[3]*ct[4]*ct[4] + m[5]*ct[5]*ct[5] \ + + 2.0*(m[1]*ct[3]*ct[4] + m[2]*ct[3]*ct[5] + m[4]*ct[4]*ct[5]) - dd; + + d2 = m[0]*ct[6]*ct[6] + m[3]*ct[7]*ct[7] + m[5]*ct[8]*ct[8] \ + + 2.0*(m[1]*ct[6]*ct[7] + m[2]*ct[6]*ct[8] + m[4]*ct[7]*ct[8]) - dd; + + d3 = m[0]*ct[9]*ct[9] + m[3]*ct[10]*ct[10] + m[5]*ct[11]*ct[11] \ + + 2.0*(m[1]*ct[9]*ct[10] + m[2]*ct[9]*ct[11] + m[4]*ct[10]*ct[11]) - dd; + + ux = ct[3] - ct[0]; + uy = ct[4] - ct[1]; + uz = ct[5] - ct[2]; + + vx = ct[6] - ct[0]; + vy = ct[7] - ct[1]; + vz = ct[8] - ct[2]; + + wx = ct[9] - ct[0]; + wy = ct[10] - ct[1]; + wz = ct[11] - ct[2]; + + /* M.u */ + ax = m[0]*ux + m[1]*uy + m[2]*uz; + ay = m[1]*ux + m[3]*uy + m[4]*uz; + az = m[2]*ux + m[4]*uy + m[5]*uz; + + bx = m[0]*vx + m[1]*vy + m[2]*vz; + by = m[1]*vx + m[3]*vy + m[4]*vz; + bz = m[2]*vx + m[4]*vy + m[5]*vz; + + cx = m[0]*wx + m[1]*wy + m[2]*wz; + cy = m[1]*wx + m[3]*wy + m[4]*wz; + cz = m[2]*wx + m[4]*wy + m[5]*wz; + + /* center */ + c[0] = d1 *(by*cz - bz*cy) - d2 * (ay*cz - az*cy) + d3 * (ay*bz - az*by); + c[1] = d1 *(bz*cx - bx*cz) - d2 * (az*cx - ax*cz) + d3 * (az*bx - ax*bz); + c[2] = d1 *(bx*cy - by*cx) - d2 * (ax*cy - ay*cx) + d3 * (ax*by - ay*bx); + + det = ax * (by*cz - bz*cy) - ay * (bx*cz - bz*cx) + az * (bx*cy - cx*by); + det = 1.0 / (2.0*det); + + c[0] *= det; + c[1] *= det; + c[2] *= det; + + /* radius (squared) */ + ux = ct[0] - c[0]; + uy = ct[1] - c[1]; + uz = ct[2] - c[2]; + *rad = m[0]*ux*ux + m[3]*uy*uy + m[5]*uz*uz \ + + 2.0*(m[1]*ux*uy + m[2]*ux*uz + m[4]*uy*uz); + + return(1); +} diff --git a/contrib/mmg3d/build/sources/chkmsh.c b/contrib/mmg3d/build/sources/chkmsh.c new file mode 100644 index 0000000000..1b492fdb88 --- /dev/null +++ b/contrib/mmg3d/build/sources/chkmsh.c @@ -0,0 +1,182 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define EPSLOC 1.00005 + + +int MMG_chkmsh(pMesh mesh,int severe,int base) { + pPoint ppt; + pTetra pt1,pt2; + List list; + int *adja,*adja1,adj,adj1,k,kk,l,nk,i,j,ip,iadr,lon,len; + unsigned char voy,voy1; + + for (k=1; k<=mesh->ne; k++) { + pt1 = &mesh->tetra[k]; + if ( !pt1->v[0] ) continue; + iadr = (k-1)*4 + 1; + adja = &mesh->adja[iadr]; + + for (i=0; i<4; i++) { + adj = adja[i] / 4; + voy = adja[i] % 4; + if ( !adj ) continue; + + if ( adj == k ) { + fprintf(stdout," 1. Wrong adjacency %d %d\n",k,adj); + printf("k %d: %d %d %d %d\n",k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + printf("adj (%d): %d %d %d %d\n", + k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4); + exit(1); + } + pt2 = &mesh->tetra[adj]; + if ( !pt2->v[0] ) { + fprintf(stdout," 4. Invalid adjacent %d %d\n",adj,k); + printf("sommets k %d: %d %d %d %d\n", + k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + printf("sommets adj %d: %d %d %d %d\n", + adj,pt2->v[0],pt2->v[1],pt2->v[2],pt2->v[3]); + printf("numeros adj %d: %d %d %d %d\n",k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4); + exit(1); + } + iadr = (adj-1)*4 + 1; + adja1 = &mesh->adja[iadr]; + adj1 = adja1[voy] / 4; + voy1 = adja1[voy] % 4; + if ( adj1 != k || voy1 != i ) { + fprintf(stdout," 2. Wrong adjacency %d %d\n",k,adj1); + printf("k %d: %d %d %d %d\n",k,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + printf("a %d: %d %d %d %d\n", + adj,pt2->v[0],pt2->v[1],pt2->v[2],pt2->v[3]); + printf("adj(%d): %d %d %d %d\n", + k,adja[0]/4,adja[1]/4,adja[2]/4,adja[3]/4); + printf("adj(%d): %d %d %d %d\n", + adj,adja1[0]/4,adja1[1]/4,adja1[2]/4,adja1[3]/4); + exit(1); + } + } + } + + /* Delaunay criterion */ +/* + for (k=1; k<=mesh->ne; k++) { + pt1 = &mesh->tetra[k]; + if ( !pt1->v[0] ) continue; + iadr = (k-1)*4 + 1; + adja = &mesh->adja[iadr]; + if ( !cenrad(mesh,k,c,&ray) ) continue; + + for (i=0; i<4; i++) { + if ( !adja[i] ) continue; + adj = adja[i] / 4; + voy = adja[i] % 4; + pt2 = &mesh->tetra[adj]; + + ppt = &mesh->point[ pt2->v[voy] ]; + dd = (ppt->c[0] - c[0]) * (ppt->c[0] - c[0]) \ + + (ppt->c[1] - c[1]) * (ppt->c[1] - c[1]) \ + + (ppt->c[2] - c[2]) * (ppt->c[2] - c[2]); + if ( EPSLOC*EPSLOC*dd < ray ) { + fprintf(stdout," ## Non-Delaunay mesh: %.14f < %.14f\n",dd,ray); + exit(1); + } + } + } +*/ + + if ( !severe ) return(1); + + for (k=1; k<=mesh->ne; k++) { + pt1 = &mesh->tetra[k]; + if ( !pt1->v[0] ) continue; + else if (pt1->flag < base ) continue; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + + for (i=0; i<4; i++) { + adj = (adja[i]-1) / 4 + 1; + voy = (adja[i]-1) % 4; + if ( !adj ) continue; + + ip = pt1->v[i]; + ppt = &mesh->point[ip]; + if ( ppt->tag & M_UNUSED ) { + fprintf(stdout," 6. Unused vertex %d %d\n",k,ip); + printf("%d %d %d %d\n",pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + exit(1); + } + lon = MMG_boulep(mesh,k,i,&list); + for (l=1; l<=lon; l++) { + kk = list.tetra[l] / 4; + nk = list.tetra[l] % 4; + pt2 = &mesh->tetra[kk]; + if ( pt2->v[nk] != ip ) { + fprintf(stdout," 5. Wrong ball %d, %d\n",ip,pt2->v[nk]); + exit(1); + } + } + if ( lon < 1 ) continue; + len = 0; + for (kk=1; kk<=mesh->ne; kk++) { + pt2 = &mesh->tetra[kk]; + if ( !pt2->v[0] ) continue; + for (j=0; j<4; j++) + if ( pt2->v[j] == ip ) { + len++; + break; + } + } + if ( len != lon ) { + fprintf(stdout," 7. Incorrect ball %d: %d %d\n",pt1->v[i],lon,len); + exit(1); + } + } + } + + /*fprintf(stdout," ** MESH STRUCTURE IS OK\n");*/ + return(1); +} diff --git a/contrib/mmg3d/build/sources/chrono.c b/contrib/mmg3d/build/sources/chrono.c new file mode 100644 index 0000000000..ba4482e177 --- /dev/null +++ b/contrib/mmg3d/build/sources/chrono.c @@ -0,0 +1,142 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* + * simulation of a chronograph + * in : tim + * out: tim.dtim = elapsed time in micro-secs + * tim.ptim = elapsed time in secs + * tim.call = number of calls + * + * Written by Pascal J. Frey + * email: Pascal.Frey@inria.fr, 1999 +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <math.h> +#include <stdlib.h> +#include "chrono.h" + + +/* return elapsed time in secs. */ +static double diftim(time_t t2,time_t t1) { + struct tm *ptm; + double tim; + int hh1,mm1,ss1,hh2,mm2,ss2; + + ptm = localtime(&t1); + hh1 = ptm->tm_hour; + mm1 = ptm->tm_min; + ss1 = ptm->tm_sec; + + ptm = localtime(&t2); + hh2 = ptm->tm_hour; + mm2 = ptm->tm_min; + ss2 = ptm->tm_sec; + if ( hh2 < hh1 ) hh2 += 24; + + tim = 3600.0*(hh2-hh1); + tim += 60.0*(mm2-mm1); + tim += ss2-ss1; + + return(tim); +} + + +/* get system and user times in micro-seconds */ +void TIM_chrono(int cmode,TIM_mytime *ptt) { + time_t tt; + + if ( cmode == RESET ) { + ptt->dtim = clock(); + ptt->ctim = 0.0f; + ptt->ptim = 0; + ptt->call = 0; + } + else { + ptt->dtim = difftime(clock(),ptt->dtim); /* in secs */ + if ( cmode == ON ) { + ptt->ptim = time(NULL); + ptt->call++; + } + else if ( cmode == OFF ) { + tt = time(NULL); + ptt->ctim += diftim(tt,ptt->ptim); + ptt->ptim = 0; + } + } +} + + +/* return time (converted in secs */ +double TIM_gttime(TIM_mytime t) { + + if ( t.ctim < MAXCLK ) + return(t.dtim / (double)CLOCKS_PER_SEC); + else + return(t.ctim); +} + + +/* initialize time table */ +void TIM_tminit(TIM_mytime *t,int maxtim) { + int k; + + for (k=0; k<maxtim; k++) { + t[k].dtim = clock(); + t[k].ptim = 0; + t[k].ctim = 0.0; + t[k].call = 0; + } +} + + +#ifdef __cplusplus +} +#endif + diff --git a/contrib/mmg3d/build/sources/chrono.h b/contrib/mmg3d/build/sources/chrono.h new file mode 100644 index 0000000000..2df3774828 --- /dev/null +++ b/contrib/mmg3d/build/sources/chrono.h @@ -0,0 +1,77 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include <time.h> + +#ifndef ON +#define RESET 0 +#define ON 1 +#define OFF 2 +#endif + +#define TIMEMAX 16 +#define MAXCLK ( 1073741823. / (double)CLOCKS_PER_SEC ) + + +typedef struct TIM_mytime { + double ctim,dtim; + time_t ptim; + short call; +} TIM_mytime; + + +/* prototypes */ +void TIM_chrono(int cmode,TIM_mytime *ptt); +double TIM_gttime(TIM_mytime t); +void TIM_tminit(TIM_mytime *t,int maxtim); + + +#ifdef __cplusplus +} +#endif diff --git a/contrib/mmg3d/build/sources/colpoi.c b/contrib/mmg3d/build/sources/colpoi.c new file mode 100644 index 0000000000..52c23ad3c5 --- /dev/null +++ b/contrib/mmg3d/build/sources/colpoi.c @@ -0,0 +1,523 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define LLONG1 1.41//1.9//1.41 + +int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex; + + +/* collapse edge b->a (i.e. remove b) */ +int MMG_colpoi(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef) { + pTetra pt,pt1; + pPoint pa,pb,ppt; + double coor[3],crit,cal; + double solu[6],len,*ca,*cb,*ma,*mb; + int *adja,*adja1,base,i,j,l,kk,nk,adj,voy,iadr,ik,ielv,lon,na,nb; + int adj1,voy1,s1,iadb,iada,ipb,vois[4],vois1[4],ii,jj,iare1,iare2; + static List list; + + pt = &mesh->tetra[iel]; + lon = MMG_boulep(mesh,iel,ib,&list); + if ( lon < 1 ) return(0); + /* topological-geometric checks */ + base = ++mesh->mark; + na = pt->v[ia]; + nb = pt->v[ib]; + pa = &mesh->point[na]; + pb = &mesh->point[nb]; + ca = &pa->c[0]; + + crit = pt->qual; + for (l=2; l<=lon; l++) { + kk = list.tetra[l] >> 2; + cal = mesh->tetra[kk].qual;//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,kk) : MMG_caltet_iso(mesh,sol,kk); + if ( cal > crit ) crit = cal; + } + crit *= coef; + //assert(crit < 1e20); + + /* change coords of pb */ + iada = (na-1)*sol->offset + 1; + ma = &sol->met[iada]; + iadb = (nb-1)*sol->offset + 1; + memcpy(coor, pb->c,3*sizeof(double)); + memcpy(pb->c,pa->c,3*sizeof(double)); + memcpy(solu,&sol->met[iadb],sol->offset*sizeof(double)); + memcpy(&sol->met[iadb],&sol->met[iada],sol->offset*sizeof(double)); + + /* avoid recreating existing elt */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] < 0 ) continue; + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + + pt1 = &mesh->tetra[kk]; + s1 = pt1->v[0]; + + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + adj = adja[nk] >> 2; + if ( !adj ) continue; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (j=0; j<4; j++) + if ( vois[j] == kk ) { + pt1 = &mesh->tetra[adj]; + s1 = pt1->v[j]; + break; + } + if ( s1 == na ) { + MMG_nex++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); + return(0); + } + } + + /* topological check */ + for (l=1; l<=lon; l++) { + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + /* mark elts of shell a-b */ + pt1 = &mesh->tetra[kk]; + for (i=0; i<4; i++) { + if ( pt1->v[i] == na ) { + list.tetra[l] = -list.tetra[l]; + pt1->mark = base; + break; + } + } + + + if ( pt1->mark == base ) continue; + /* check lengths */ + for (i=0; i<3; i++) { + ipb = pt1->v[ MMG_idir[nk][i] ]; + ppt = &mesh->point[ipb]; + cb = &ppt->c[0]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + // if(cal < 1e-10) printf("(%e) long %d : %e\n",cal,i,MMG_length(ca,cb,ma,mb),crit/60.); + if ( ppt->mark < base ) { + len = MMG_length(ca,cb,ma,mb); + if ( len > crit/60. ) { + MMG_nlen++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); + //printf("len reject %e %e\n",len,LLONG1); + return(0); + } + ppt->mark = base; + } + } + + /* check volume of remaining elt */ + cal = MMG_voltet(mesh,kk);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,iel) : MMG_caltet_iso(mesh,sol,iel); + list.qual[l] = MMG_caltet(mesh,sol,kk); + //if( cal < 1e-10 && cal >= 1e-15) printf("cal : %e %e\n",cal,MMG_caltet_ani(mesh,sol,kk)); + if ( cal < 1e-10/*crit*/ ) { + MMG_ncal++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); +//printf("cal reject\n"); + return(0); + } + + } + /* verif topo */ + for (l=1; l<=lon; l++) { + ik = abs(list.tetra[l]); + kk = ik >> 2; + nk = ik % 4; + pt1 = &mesh->tetra[kk]; + if ( pt1->mark != base ) continue; + + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + ielv = adja[nk] >> 2; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + + for (i=0; i<4; i++) { + if ( i == nk ) continue; + adj = vois[i]; + pt1 = &mesh->tetra[adj]; + if ( pt1->mark == base ) continue; + adja1 = &mesh->adja[ (adj-1)*4 + 1 ]; + vois1[0] = adja1[0] >> 2; + vois1[1] = adja1[1] >> 2; + vois1[2] = adja1[2] >> 2; + vois1[3] = adja1[3] >> 2; + for (j=0; j<4; j++) { + adj1 = vois1[j]; + if ( pt1->v[j] == nb && adj1 == ielv ) { + MMG_ntopo++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); + return(0); + } + } + } + } + + /* update topo: shell */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] > 0 ) continue; + + kk = -list.tetra[l] >> 2; + nk = -list.tetra[l] % 4; + + pt1 = &mesh->tetra[kk]; + pt1->qual = list.qual[l]; + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + adj = adja[nk] >> 2; + voy = adja[nk] % 4; + adj1 = 0; + voy1 = 0; + for (j=0; j<4; j++) { + if ( pt1->v[j] == na ) { + adj1 = adja[j] >> 2; + voy1 = adja[j] % 4; + if ( adj1 ) { + iadr = (adj1-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy1] = 4*adj + voy; + mesh->tetra[adj1].bdryref[voy1] = pt1->bdryref[nk]; + for(ii=0 ; ii<3 ; ii++) { + if(!pt1->bdryinfo[MMG_iarf[nk][ii]]) continue; + iare1 = pt1->v[MMG_iare[MMG_iarf[nk][ii]][0]]; + iare2 = pt1->v[MMG_iare[MMG_iarf[nk][ii]][1]]; + if(iare1==na) { + iare1=nb; + } else if(iare2==na) { + iare2=nb; + } + else { + continue; + } + for(jj=0 ; jj<3 ; jj++) { + // printf("iare %d %d -- %d %d\n",iare1,iare2,mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]], + // mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]); + if((iare1==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]] && + iare2==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]) || + (iare2==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]] && + iare1==mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]])) { + mesh->tetra[adj1].bdryinfo[MMG_iarf[voy1][jj]] = pt1->bdryinfo[MMG_iarf[nk][ii]]; + break; + } + } + assert(jj<3); + } + + } + break; + } + } + if ( adj ) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = 4*adj1 + voy1; + if(!adj1) { + mesh->tetra[adj].bdryref[voy] = pt1->bdryref[j]; + for(ii=0 ; ii<3 ; ii++) { + if(!pt1->bdryinfo[MMG_iarf[j][ii]]) continue; + iare1 = pt1->v[MMG_iare[MMG_iarf[j][ii]][0]]; + iare2 = pt1->v[MMG_iare[MMG_iarf[j][ii]][1]]; + if(iare1==na) { + iare1=nb; + } else if(iare2==na) + iare2=nb; + else + continue; + for(jj=0 ; jj<3 ; jj++) { + // printf("iare %d %d -- %d %d\n",iare1,iare2,mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][0]], + // mesh->tetra[adj1].v[MMG_iare[MMG_iarf[voy1][jj]][1]]); + if((iare1==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][0]] && + iare2==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][1]]) || + (iare2==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][0]] && + iare1==mesh->tetra[adj].v[MMG_iare[MMG_iarf[voy][jj]][1]])) { + mesh->tetra[adj1].bdryinfo[MMG_iarf[voy1][jj]] = pt1->bdryinfo[j]; + break; + } + } + assert(jj<3); + } + } + } + MMG_delElt(mesh,kk); + } + + /* update topo: ball */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] < 0 ) continue; + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[kk]; + pt1->v[nk] = na; + pt1->flag = mesh->flag; + pt1->qual = list.qual[l]; + pt1->edge &= ~(1 << MMG_arpt[nk][0]); + pt1->edge &= ~(1 << MMG_arpt[nk][1]); + pt1->edge &= ~(1 << MMG_arpt[nk][2]); + } + + /* delete vertex */ + memcpy(pb->c,coor,3*sizeof(double)); + pa->mark = mesh->flag; + + return(1); +} +/* collapse edge b->a (i.e. remove b) */ +int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef) { + pTetra pt,pt1; + pPoint pa,pb,ppt; + double coor[3],crit,cal,len; + double solu[6],*ca,*cb,*ma,*mb; + int *adja,*adja1,base,i,j,l,kk,nk,adj,voy,iadr,ik,ielv,lon,na,nb; + int adj1,voy1,s1,ipb,iadb,iada; + static List list; + + pt = &mesh->tetra[iel]; + lon = MMG_boulep(mesh,iel,ib,&list); + if ( lon < 1 ) return(0); + + /* topological-geometric checks */ + base = ++mesh->mark; + na = pt->v[ia]; + nb = pt->v[ib]; + pa = &mesh->point[na]; + pb = &mesh->point[nb]; + ca = &pa->c[0]; + + crit = pt->qual; + for (l=2; l<=lon; l++) { + kk = list.tetra[l] >> 2; + cal = MMG_caltet(mesh,sol,kk); + if ( cal > crit ) crit = cal; + } + crit *= coef; + + /* change coords of pb */ + iada = (na-1)*sol->offset + 1; + ma = &sol->met[iada]; + iadb = (nb-1)*sol->offset + 1; + memcpy(coor, pb->c,3*sizeof(double)); + memcpy(pb->c,pa->c,3*sizeof(double)); + memcpy(solu,&sol->met[iadb],sol->offset*sizeof(double)); + memcpy(&sol->met[iadb],&sol->met[iada],sol->offset*sizeof(double)); + + /* avoid recreating existing elt */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] < 0 ) continue; + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + + pt1 = &mesh->tetra[kk]; + s1 = pt1->v[0]; + + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + adj = adja[nk] >> 2; + if ( !adj ) continue; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + for (j=0; j<4; j++) + if ( adja[j]/4 == kk ) { + pt1 = &mesh->tetra[adj]; + s1 = pt1->v[j]; + break; + } + if ( s1 == na ) { + MMG_nex++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); + return(0); + } + } + + /* topological check */ + for (l=1; l<=lon; l++) { + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + + /* mark elts of shell a-b */ + pt1 = &mesh->tetra[kk]; + for (i=0; i<4; i++) { + if ( pt1->v[i] == na ) { + list.tetra[l] = -list.tetra[l]; + pt1->mark = base; + break; + } + } + /* check volume of remaining elt */ + if ( pt1->mark == base ) continue; + cal = MMG_caltet(mesh,sol,kk); + list.qual[l] = cal; + if ( cal > crit ) { + MMG_ncal++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); +//printf("bad quality : %f > %f\n",cal,crit); + return(0); + } + + /* check lengths */ + for (i=0; i<3; i++) { + ipb = pt1->v[ MMG_idir[nk][i] ]; + ppt = &mesh->point[ipb]; + cb = &ppt->c[0]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + if ( ppt->mark < base ) { + len = MMG_length(ca,cb,ma,mb); + if ( len > 1.51 ) { + MMG_nlen++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); +//printf("bad MMG_length : %f > %f\n",len,1.51); + return(0); + } + ppt->mark = base; + } + } + } + + /* verif topo */ + for (l=1; l<=lon; l++) { + ik = abs(list.tetra[l]); + kk = ik >> 2; + nk = ik % 4; + pt1 = &mesh->tetra[kk]; + if ( pt1->mark != base ) continue; + + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + ielv = adja[nk] >> 2; + + for (i=0; i<4; i++) { + if ( i == nk ) continue; + adj = adja[i] >> 2; + pt1 = &mesh->tetra[adj]; + if ( pt1->mark == base ) continue; + adja1 = &mesh->adja[ (adj-1)*4 + 1 ]; + for (j=0; j<4; j++) { + adj1 = adja1[j] >> 2; + if ( pt1->v[j] == nb && adj1 == ielv ) { + MMG_ntopo++; + memcpy(pb->c,coor,3*sizeof(double)); + memcpy(&sol->met[iadb],solu,sol->offset*sizeof(double)); + return(0); + } + } + } + } + + /* update topo: shell */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] > 0 ) continue; + + kk = -list.tetra[l] >> 2; + nk = -list.tetra[l] % 4; + + pt1 = &mesh->tetra[kk]; + pt1->qual = list.qual[l]; + iadr = (kk-1)*4 + 1; + adja = &mesh->adja[iadr]; + adj = adja[nk] >> 2; + voy = adja[nk] % 4; + adj1 = 0; + voy1 = 0; + for (j=0; j<4; j++) { + if ( pt1->v[j] == na ) { + adj1 = adja[j] >> 2; + voy1 = adja[j] % 4; + if ( adj1 ) { + iadr = (adj1-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy1] = 4*adj + voy; + mesh->tetra[adj1].bdryref[voy1] = pt1->bdryref[nk]; + } + break; + } + } + if ( adj ) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = 4*adj1 + voy1; + if(!adj1) + mesh->tetra[adj].bdryref[voy] = pt1->bdryref[j]; + } + MMG_delElt(mesh,kk); + } + + /* update topo: ball */ + for (l=1; l<=lon; l++) { + if ( list.tetra[l] < 0 ) continue; + kk = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[kk]; + pt1->v[nk] = na; + pt1->flag = mesh->flag; + pt1->qual = list.qual[l]; + pt1->edge &= ~(1 << MMG_arpt[nk][0]); + pt1->edge &= ~(1 << MMG_arpt[nk][1]); + pt1->edge &= ~(1 << MMG_arpt[nk][2]); + } + + /* delete vertex */ + memcpy(pb->c,coor,3*sizeof(double)); + pa->mark = mesh->flag; + + return(1); +} diff --git a/contrib/mmg3d/build/sources/coquil.c b/contrib/mmg3d/build/sources/coquil.c new file mode 100644 index 0000000000..c351552e47 --- /dev/null +++ b/contrib/mmg3d/build/sources/coquil.c @@ -0,0 +1,106 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* find all tets sharing edge ia of iel */ +int MMG_coquil(pMesh mesh,int iel,int ia,pList list) { + pTetra pt; + int *adja,i,iadr,adj,base,na,nb,ipa,ipb,piv,ilist,kref; + + if ( iel < 1 ) return(0); + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(0); + + base = ++mesh->mark; + pt->mark = base; + kref = pt->ref; + ilist = 1; + list->tetra[ilist] = 6*iel + ia; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adj = adja[ MMG_ifar[ia][0] ] >> 2; + piv = pt->v[ MMG_ifar[ia][1] ]; + if ( !adj ) return(0); + + na = pt->v[ MMG_iare[ia][0] ]; + nb = pt->v[ MMG_iare[ia][1] ]; + + while ( adj != iel ) { + pt = &mesh->tetra[adj]; + pt->mark = base; + if (kref!=pt->ref) return(0); + + /* identify edge */ + for (i=0; i<6; i++) { + ipa = MMG_iare[i][0]; + ipb = MMG_iare[i][1]; + if ( (pt->v[ipa] == na && pt->v[ipb] == nb) || + (pt->v[ipa] == nb && pt->v[ipb] == na)) break; + } + if(i==6) printf("tetra %d : %d %d %d %d -- %e\n",iel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],pt->qual); + assert(i<6); + + ++ilist; + if ( ilist > LONMAX-1 ) return(-ilist); + list->tetra[ilist] = 6*adj + i; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if ( pt->v[ MMG_ifar[i][0] ] == piv ) { + adj = adja[ MMG_ifar[i][0] ] >> 2; + piv = pt->v[ MMG_ifar[i][1] ]; + } + else { + adj = adja[ MMG_ifar[i][1] ] >> 2; + piv = pt->v[ MMG_ifar[i][0] ]; + } + + if ( !adj ) return(0); + } + + return(ilist); +} diff --git a/contrib/mmg3d/build/sources/cutelt.c b/contrib/mmg3d/build/sources/cutelt.c new file mode 100644 index 0000000000..54480498fa --- /dev/null +++ b/contrib/mmg3d/build/sources/cutelt.c @@ -0,0 +1,544 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_cutadd(pMesh mesh,pHedge hed,int icas,int k,int p0,int p1,int p2,int p3,int p4,int p5, int ref) { + pTetra pt; + pPoint ppt,pp0,pp1,pp2,pp3,pp4,pp5; + + pp0 = &mesh->point[p0]; + pp1 = &mesh->point[p1]; + pp2 = &mesh->point[p2]; + pp3 = &mesh->point[p3]; + pp4 = &mesh->point[p4]; + pp5 = &mesh->point[p5]; + mesh->np++; + ppt = &mesh->point[mesh->np]; + ppt->c[2] = (1./6.)*(pp0->c[2]+pp1->c[2]+pp2->c[2]+pp3->c[2]+pp4->c[2]+pp5->c[2]); + ppt->c[1] = (1./6.)*(pp0->c[1]+pp1->c[1]+pp2->c[1]+pp3->c[1]+pp4->c[1]+pp5->c[1]); + ppt->c[0] = (1./6.)*(pp0->c[0]+pp1->c[0]+pp2->c[0]+pp3->c[0]+pp4->c[0]+pp5->c[0]); + ppt->ref = pp0->ref; + //printf("prisme : %d %d %d %d %d %d + %d\n",p0,p1,p2,p3,p4,p5,mesh->np); + if(icas & 1) { + //printf("icas %d --> 0 ?\n",icas); + pt = &mesh->tetra[k + 1]; + pt->v[0] = p0; + pt->v[1] = p4; + pt->v[2] = p3; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p0; + pt->v[1] = p1; + pt->v[2] = p4; + pt->v[3] = mesh->np; + pt->ref = ref; + } else { + if(icas & 4) { + //printf("icas %d --> 2 ?\n",icas); + + } else { + MMG_edgePut(hed,p1,p3,2); + } + pt = &mesh->tetra[k + 1]; + pt->v[0] = p0; + pt->v[1] = p1; + pt->v[2] = p3; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p1; + pt->v[1] = p4; + pt->v[2] = p3; + pt->v[3] = mesh->np; + pt->ref = ref; + } + + if(icas & 8) { + //printf("icas %d --> 3 ?\n",icas); + pt = &mesh->tetra[k + 3]; + pt->v[0] = p1; + pt->v[1] = p2; + pt->v[2] = p5; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 4]; + pt->v[0] = p1; + pt->v[1] = p5; + pt->v[2] = p4; + pt->v[3] = mesh->np; + pt->ref = ref; + } else { + if(icas & 32) { + //printf("icas %d --> 5 ?\n",icas); + + } else { + MMG_edgePut(hed,p2,p4,2); + } + pt = &mesh->tetra[k + 3]; + pt->v[0] = p1; + pt->v[1] = p2; + pt->v[2] = p4; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 4]; + pt->v[0] = p4; + pt->v[1] = p2; + pt->v[2] = p5; + pt->v[3] = mesh->np; + pt->ref = ref; + } + + if(icas & 2) { + //printf("icas %d --> 1 ?\n",icas); + pt = &mesh->tetra[k + 5]; + pt->v[0] = p0; + pt->v[1] = p5; + pt->v[2] = p3; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 6]; + pt->v[0] = p0; + pt->v[1] = p5; + pt->v[2] = p2; + pt->v[3] = mesh->np; + pt->ref = ref; + } else { + if(icas & 16) { + //printf("icas %d --> 4 ?\n",icas); + + } else { + MMG_edgePut(hed,p2,p3,2); + } + pt = &mesh->tetra[k + 5]; + pt->v[0] = p0; + pt->v[1] = p2; + pt->v[2] = p3; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 6]; + pt->v[0] = p2; + pt->v[1] = p3; + pt->v[2] = p5; + pt->v[3] = mesh->np; + pt->ref = ref; + } + + pt = &mesh->tetra[k + 7]; + pt->v[0] = p3; + pt->v[1] = p4; + pt->v[2] = p5; + pt->v[3] = mesh->np; + pt->ref = ref; + pt = &mesh->tetra[k + 8]; + pt->v[0] = p0; + pt->v[1] = p1; + pt->v[2] = p2; + pt->v[3] = mesh->np; + pt->ref = ref; + + return(1); +} + +int MMG_cuthex(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int p6,int p7, int ref) { + pTetra pt; + int i,nu1,nu2; + + + pt = &mesh->tetra[k+1]; + pt->v[0] = p0; + pt->v[1] = p1; + pt->v[2] = p3; + pt->v[3] = p7; + pt->ref = ref; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + //if((netmp+(k-1)*6+1 ) == 2924) printf("i) %d tet %d %d %d %d\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + pt = &mesh->tetra[k+2]; + pt->v[0] = p7; + pt->v[1] = p2; + pt->v[2] = p1; + pt->v[3] = p6; + pt->ref = ref; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + //if((netmp+(k-1)*6+1 + 1) == 2924) printf("ii) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + pt = &mesh->tetra[k+3]; + pt->v[0] = p1; + pt->v[1] = p4; + pt->v[2] = p5; + pt->v[3] = p7; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + //if((netmp+(k-1)*6+1 + 2) == 2924) printf("iii) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + pt->ref = ref; + pt = &mesh->tetra[k+4]; + pt->v[0] = p7; + pt->v[1] = p4; + pt->v[2] = p0; + pt->v[3] = p1; + pt->ref = ref; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + //if((netmp+(k-1)*6+1 + 3) == 2924) printf("iv) tet %d %d %d %d\n",pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + pt = &mesh->tetra[k+5]; + pt->v[0] = p1; + pt->v[1] = p6; + pt->v[2] = p7; + pt->v[3] = p5; + pt->ref = ref; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + pt = &mesh->tetra[k+6]; + pt->v[0] = p1; + pt->v[1] = p3; + pt->v[2] = p2; + pt->v[3] = p7; + pt->ref = ref; + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + MMG_edgePut(hed,nu1,nu2,2); + } + return(1); +} + +int MMG_cutprism(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int ref) { + pTetra pt; + double vol; + int t0,t1,t2; + char icas; + int ddebug; + + vol= MMG_quickvol(mesh->point[p0].c,mesh->point[p1].c,mesh->point[p2].c,mesh->point[p3].c); + if(vol<0) { + printf("inversion"); + t0 = p0; + t1 = p1; + t2 = p2; + p0 = p3; + p1 = p4; + p2 = p5; + p3 = t0; + p4 = t1; + p5 = t2; + } + if(k==606 || k==605 || k==604 || k==609 || k==608 || k==607) ddebug=1; + else ddebug=0; + ddebug=0; + if(ddebug) printf("k = %d : %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p5); + + icas = 0; + + //find edge 2 : p1-p3 then edge 0 : 0 4 + if(!MMG_edgePoint(hed,p1,p3)) { + if(MMG_edgePoint(hed,p0,p4)) + icas |= 1; + } else { + icas |= 4; + } + //find edge 5 : p2-p4 then edge 3 : 1 5 + if(!MMG_edgePoint(hed,p2,p4)) { + if(MMG_edgePoint(hed,p1,p5)) + icas |= 8; + } else { + icas |= 32; + } + //find edge 4 : p2-p3 then edge 1 : 0 5 + if(!MMG_edgePoint(hed,p2,p3)) { + if(MMG_edgePoint(hed,p0,p5)) + icas |= 2; + } else { + icas |= 16; + } + if(icas > 55) { + fprintf(stdout,"grosgros bug %d\n",icas); + exit(0); + } + if(ddebug) printf("on trouve %d\n",icas); + + switch(icas) { + case 0: + if(ddebug) printf("on rajoute %d %d -- %d %d -- %d %d\n",p0,p4,p1,p5,p0,p5); + MMG_edgePut(hed,p2,p4,2); + MMG_edgePut(hed,p1,p3,2); + MMG_edgePut(hed,p3,p2,2);//MMG_edgePut(hed,p2,p3,2); + icas = 52; + break; + case 1: + MMG_edgePut(hed,p1,p5,2); + MMG_edgePut(hed,p0,p5,2); + icas = 11;//25; + break; + case 2: + MMG_edgePut(hed,p1,p5,2); + MMG_edgePut(hed,p0,p4,2); + icas = 11;//14 + break; + case 3: + MMG_edgePut(hed,p1,p5,2); + icas = 11;//35; + break; + case 4: + MMG_edgePut(hed,p2,p4,2);//MMG_edgePut(hed,p1,p5,2); + MMG_edgePut(hed,p2,p3,2);//MMG_edgePut(hed,p0,p5,2); + icas = 52;//14; + break; + case 6: + MMG_edgePut(hed,p1,p5,2); + icas = 14; + break; + case 8: + MMG_edgePut(hed,p0,p5,2); + MMG_edgePut(hed,p0,p4,2); + icas = 11;//14; + break; + case 9: + MMG_edgePut(hed,p0,p5,2); + icas = 11;//25; + break; + case 10: + MMG_edgePut(hed,p0,p4,2); + icas = 11;//14; + break; + case 12: + MMG_edgePut(hed,p0,p5,2); + icas = 14; + break; + case 16: + MMG_edgePut(hed,p2,p4,2);//MMG_edgePut(hed,p1,p5,2); + MMG_edgePut(hed,p3,p1,2);//MMG_edgePut(hed,p1,p3,2); + icas = 52;//28; + break; + case 17: + MMG_edgePut(hed,p4,p2,2); + icas = 49;//25; + break; + case 20: + MMG_edgePut(hed,p2,p4,2); //MMG_edgePut(hed,p1,p5,2); + icas = 52;//28; + break; + case 24: + MMG_edgePut(hed,p1,p3,2); + icas = 28;//25; + break; + case 32: + MMG_edgePut(hed,p1,p3,2);//MMG_edgePut(hed,p0,p4,2); + MMG_edgePut(hed,p2,p3,2);//MMG_edgePut(hed,p0,p5,2); + icas = 52;//35; + break; + case 33: + MMG_edgePut(hed,p0,p5,2); + icas = 35; + break; + case 34: + MMG_edgePut(hed,p0,p4,2); + icas = 35; + break; + case 36: + MMG_edgePut(hed,p3,p2,2); + icas = 52; + break; + case 48: + MMG_edgePut(hed,p1,p3,2);//MMG_edgePut(hed,p0,p4,2); + icas = 52;//49; + break; + default: + //5,7,11,13,15,18,19,21,22,23,26,27,29,30,31,37,39,40,41,42,43,44,45,46,47,50,51,52,53,54,55: + //printf("icas imposssss %d\n",icas); + //exit(0); + break; + + } + if(ddebug) printf("du coup %d\n",icas); + switch(icas) { + case 14: + pt = &mesh->tetra[k + 1]; + pt->v[0] = p5; + pt->v[1] = p1; + pt->v[2] = p2; + pt->v[3] = p0; + pt->ref = ref;//1;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p3; + pt->v[1] = p5; + pt->v[2] = p1; + pt->v[3] = p0; + pt->ref = ref;//1;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p3; + pt->v[1] = p4; + pt->v[2] = p1; + pt->v[3] = p5; + pt->ref = ref;//1;//ref; + break; + case 11://25: //D3 --> bug! + if(ddebug) printf("on create %d %d %d %d -- %d %d %d %d -- %d %d %d %d\n",p0,p4,p3,p5,p0,p1,p4,p5,p5,p1,p2,p0); + pt = &mesh->tetra[k + 1]; + pt->v[0] = p0; + pt->v[1] = p4; + pt->v[2] = p3; + pt->v[3] = p5; + pt->ref = ref;//3;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p0; + pt->v[1] = p1; + pt->v[2] = p4; + pt->v[3] = p5; + pt->ref = ref;//3;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p5; + pt->v[1] = p1; + pt->v[2] = p2; + pt->v[3] = p0; + pt->ref = ref;//3;//ref; + break; + case 28: //D2 + pt = &mesh->tetra[k + 1]; + pt->v[0] = p4; + pt->v[1] = p5; + pt->v[2] = p1; + pt->v[3] = p3; + pt->ref = ref;//2;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p1; + pt->v[1] = p2; + pt->v[2] = p5; + pt->v[3] = p3; + pt->ref = ref;//2;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p2; + pt->v[1] = p3; + pt->v[2] = p1; + pt->v[3] = p0; + pt->ref = ref;//2;//ref; + break; + case 35: //D4 --> ok + pt = &mesh->tetra[k + 1]; + pt->v[0] = p0; + pt->v[1] = p4; + pt->v[2] = p3; + pt->v[3] = p5; + pt->ref = ref;//4;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p0; + pt->v[1] = p4; + pt->v[2] = p5; + pt->v[3] = p2; + pt->ref = ref;//4;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p0; + pt->v[1] = p2; + pt->v[2] = p4; + pt->v[3] = p1; + pt->ref = ref;//4;//ref; + break; + case 52: + pt = &mesh->tetra[k + 1]; + pt->v[0] = p2; + pt->v[1] = p4; + pt->v[2] = p5; + pt->v[3] = p3; + pt->ref = ref;//6;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p2; + pt->v[1] = p4; + pt->v[2] = p1; + pt->v[3] = p3; + pt->ref = ref;//6;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p3; + pt->v[1] = p0; + pt->v[2] = p1; + pt->v[3] = p2; + pt->ref = ref;//6;//ref; + break; + case 49: //D5 + pt = &mesh->tetra[k + 1]; + pt->v[0] = p0; + pt->v[1] = p4; + pt->v[2] = p3; + pt->v[3] = p2; + pt->ref = ref;//5;//ref; + pt = &mesh->tetra[k + 2]; + pt->v[0] = p3; + pt->v[1] = p2; + pt->v[2] = p4; + pt->v[3] = p5; + pt->ref = ref;//5;//ref; + pt = &mesh->tetra[k + 3]; + pt->v[0] = p0; + pt->v[1] = p2; + pt->v[2] = p1; + pt->v[3] = p4; + pt->ref = ref;//5;//ref; + break; + default: + //5,7,11,13,15,18,19,21,22,23,26,27,29,30,31,37,39,40,41,42,43,44,45,46,47,50,51,52,53,54,55: + MMG_cutadd(mesh,hed,icas,k,p0,p1,p2,p3,p4,p5,ref); + + //printf("icas imposssss %d\n",icas); + return(0); + //exit(0); + break; + } + return(1); +} \ No newline at end of file diff --git a/contrib/mmg3d/build/sources/defines.h b/contrib/mmg3d/build/sources/defines.h new file mode 100644 index 0000000000..2d71e945a9 --- /dev/null +++ b/contrib/mmg3d/build/sources/defines.h @@ -0,0 +1,97 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#define EPS 1.e-06 +#define EPS1 1.e-9 +#define EPS2 1.e-12 +#define EPSOK 1.e-18 +#define EPS30 1.e-30 + +#define ALPHAC 0.20412415 /* sqrt(6)/12 */ +#define ALPHAD 0.04811252 /* 1.0/(12*sqrt(3)) */ +#define BETAC 0.03928371 /* sqrt(2)/36 */ + +#define LLONG 1.3 +#define LSHORT 0.72 +#define LFILT 0.7 +#define QDEGRAD 2.45 + +#define LONMAX 4096 +#define NPMAX 500000 +#define NTMAX 1000000 +#define NEMAX 3000000 + +#define PRECI 1 +#define BUCKSIZ 64 + +#define min(a,b) ( (a) < (b) ? (a) : (b) ) +#define max(a,b) ( (a) < (b) ? (b) : (a) ) + +#define M_NOTAG (0) +#define M_UNUSED (1 << 0) +#define M_BDRY (1 << 1) +#define M_MOVE (1 << 2) +#define M_CAVITY (1 << 3) +//#define M_CORNER (1 << 4) +//#define M_REQUIRED (1 << 5) +//#define M_RIDGE_GEO(1 << 6) +//#define M_RIDGE_REF(1 << 7) +#define ALL_BDRY 63 + +#ifdef INT_MAX +#undef INT_MAX +#undef SHORT_MAX +#endif +#define INT_MAX 0x7fffffff +#define SHORT_MAX 0x7fff + + +extern unsigned char MMG_idir[4][3]; +extern unsigned char MMG_inxt[7]; +extern unsigned char MMG_iarf[4][3]; +extern unsigned char MMG_iare[6][2]; +extern unsigned char MMG_ifar[6][2]; +extern unsigned char MMG_isar[6][2]; +extern unsigned char MMG_arpt[4][3]; diff --git a/contrib/mmg3d/build/sources/delaunay.c b/contrib/mmg3d/build/sources/delaunay.c new file mode 100644 index 0000000000..e53a0e6a0c --- /dev/null +++ b/contrib/mmg3d/build/sources/delaunay.c @@ -0,0 +1,813 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "eigenv.h" +#include "mesh.h" + +#define EPSRAD 1.00005 +#define EPSCON 5.0e-4//1.e-4//1.0e-3 +#define VOLMIN 1.e-10//1.0e-15 --> vol negatif qd on rejoue + + +int MMG_cas; +extern int MMG_npuiss,MMG_nvol,MMG_npres; + + +/* cavity -> ball */ +int MMG_delone(pMesh mesh,pSol sol,int ip,pList list,int ilist) { + pPoint ppt; + pTetra pt,pt1; + int *adja,*adjb,i,j,k,l,m,iel,jel,old,v[3],iadr,base,size; + int vois[4],ii,kk,iare1,iare2; + short i1; + char alert; + int tref; + if ( mesh->ne + 2*ilist > mesh->nemax ) return(0); + base = mesh->mark; + /* external faces */ + size = 0; + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + for (i=0; i<4; i++) { + jel = vois[i]; + if ( !jel || mesh->tetra[jel].mark != base ) { + for (j=0; j<3; j++) { + i1 = MMG_idir[i][j]; + ppt = &mesh->point[ pt1->v[i1] ]; + ppt->tag |= M_CAVITY; + } + size++; + } + } + } + + /* check isolated vertex */ + alert = 0; + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt1->v[i] ]; + if ( !(ppt->tag & M_CAVITY) ) alert = 1; + } + } + /* reset tag */ + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt1->v[i] ]; + ppt->tag &= ~M_CAVITY; + } + } + if ( alert ) return(-1); + /* hash table params */ + if ( size > 3*LONMAX ) return(0); + list->hedg.size = size; + list->hedg.nhmax = 3*size+1; + list->hedg.hnxt = size; + memset(list->hedg.item,0,list->hedg.nhmax*sizeof(hedge)); + for (k=size; k<list->hedg.nhmax; k++) + list->hedg.item[k].nxt = k+1; + + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0]; + vois[1] = adja[1]; + vois[2] = adja[2]; + vois[3] = adja[3]; + pt = &mesh->tetra[old]; + + for (i=0; i<4; i++) { + jel = vois[i] >> 2; + j = vois[i] % 4; + + /* external face */ + if ( !jel || (mesh->tetra[jel].mark != base) ) { + iel = MMG_newElt(mesh); + if ( iel < 1 ) return(0); + pt1 = &mesh->tetra[iel]; + memcpy(pt1,pt,sizeof(Tetra)); + pt1->v[i] = ip; + pt1->qual = MMG_caltet(mesh,sol,iel); + pt1->ref = mesh->tetra[old].ref; + if(pt1->qual > 1e+18) {printf("argggg (%d) %d : %e\n",ip,iel,pt1->qual); + printf("pt1 : %d %d %d %d\n",pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]);/*exit(0);*/} + pt1->flag = mesh->flag; + pt1->edge = 0; + for(ii=0 ; ii<4 ; ii++) + pt1->bdryref[ii] = -1; + /*MAJ bdryinfo */ + for(ii=0 ; ii<6 ; ii++) + pt1->bdryinfo[ii] = 0; + for(ii=0 ; ii<3 ; ii++) { + if(!pt->bdryinfo[MMG_iarf[i][ii]]) continue; + iare1 = pt->v[MMG_iare[MMG_iarf[i][ii]][0]]; + iare2 = pt->v[MMG_iare[MMG_iarf[i][ii]][1]]; + for(kk=0 ; kk<3 ; kk++) { + if(((iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) + || ((iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) ) { + pt1->bdryinfo[MMG_iarf[i][kk]] = pt->bdryinfo[MMG_iarf[i][ii]]; + break; + } + } + assert(kk<3); + } + if(!jel || (mesh->tetra[jel].ref != pt1->ref)) { + pt1->bdryref[i] = mesh->tetra[old].bdryref[i]; + if(pt1->bdryref[i]<0) { + printf("delone : pbs sd %d : %d %d %d\n",iel,pt1->v[MMG_idir[i][0]] + ,pt1->v[MMG_idir[i][1]],pt1->v[MMG_idir[i][2]]);exit(0); + } + } + iadr = (iel-1)*4 + 1; + adjb = &mesh->adja[iadr]; + adjb[i] = adja[i]; + if ( jel ) { + iadr = (jel-1)*4 + 1; + adjb = &mesh->adja[iadr]; + adjb[j] = iel*4 + i; + } + + /* internal faces (p1,p2,ip) */ + for (j=0; j<4; j++) { + if ( j != i ) { + m = 0; + for (l=0; l<3; l++) + if ( pt1->v[ MMG_idir[j][l] ] != ip ) { + v[m] = pt1->v[ MMG_idir[j][l] ]; + m++; + } + MMG_hashEdge(mesh,&list->hedg,iel,j,v); + } + } + } + } + } + + /* remove old tetra */ + tref = mesh->tetra[list->tetra[1]].ref; + for (k=1; k<=ilist; k++) { + if(tref!=mesh->tetra[list->tetra[k]].ref) + printf("arg ref ???? %d %d\n",tref,mesh->tetra[list->tetra[k]].ref); + MMG_delElt(mesh,list->tetra[k]); + } + + ppt = &mesh->point[ip]; + ppt->flag = mesh->flag; + return(1); +} + + +/* clone of delone */ +int MMG_delons(pMesh mesh,pSol sol,pQueue queue,int ip,pList list,int ilist,double declic) { + pPoint ppt; + pTetra pt,pt1; + int *adja,*adjb,i,j,k,l,m,iel,jel,old,v[3],iadr,base,size; + int vois[4],ii,kk,iare1,iare2,tref; + short i1; + char alert; + + if ( mesh->ne + 2*ilist > mesh->nemax ) return(0); + base = mesh->mark; + + /* external faces */ + size = 0; + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + jel = adja[i] >> 2; + if ( !jel || mesh->tetra[jel].mark != base ) { + for (j=0; j<3; j++) { + i1 = MMG_idir[i][j]; + ppt = &mesh->point[ pt1->v[i1] ]; + ppt->tag |= M_CAVITY; + } + size++; + } + } + } + + /* check isolated vertex */ + alert = 0; + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt1->v[i] ]; + if ( !(ppt->tag & M_CAVITY) ) alert = 1; + } + } + /* reset tag */ + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + pt1 = &mesh->tetra[old]; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt1->v[i] ]; + ppt->tag &= ~M_CAVITY; + } + } + if ( alert ) return(-1); + + /* hash table params */ + if ( size > 3*LONMAX ) return(0); + list->hedg.size = size; + list->hedg.nhmax = 3*size+1; + list->hedg.hnxt = size; + memset(list->hedg.item,0,list->hedg.nhmax*sizeof(hedge)); + for (k=size; k<list->hedg.nhmax; k++) + list->hedg.item[k].nxt = k+1; + + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0]; + vois[1] = adja[1]; + vois[2] = adja[2]; + vois[3] = adja[3]; + pt = &mesh->tetra[old]; + + for (i=0; i<4; i++) { + jel = vois[i] >> 2; + j = vois[i] % 4; + + /* external face */ + if ( !jel || mesh->tetra[jel].mark != base ) { + iel = MMG_newElt(mesh); + if ( iel < 1 ) return(0); + pt1 = &mesh->tetra[iel]; + pt1->ref = mesh->tetra[old].ref; + mesh->point[ip].tmp = iel; + memcpy(pt1,pt,sizeof(Tetra)); + pt1->v[i] = ip; + pt1->qual = MMG_caltet(mesh,sol,iel); + pt1->flag = mesh->flag; + pt1->edge = 0; + for(ii=0 ; ii<4 ; ii++) + pt1->bdryref[ii] = -1; + /*MAJ bdryinfo */ + for(ii=0 ; ii<6 ; ii++) + pt1->bdryinfo[ii] = 0; + for(ii=0 ; ii<3 ; ii++) { + if(!pt->bdryinfo[MMG_iarf[i][ii]]) continue; + iare1 = pt->v[MMG_iare[MMG_iarf[i][ii]][0]]; + iare2 = pt->v[MMG_iare[MMG_iarf[i][ii]][1]]; + for(kk=0 ; kk<3 ; kk++) { + if(((iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) + || ((iare2==pt->v[MMG_iare[MMG_iarf[i][kk]][0]]) && (iare1==pt->v[MMG_iare[MMG_iarf[i][kk]][1]])) ) { + pt1->bdryinfo[MMG_iarf[i][kk]] = pt->bdryinfo[MMG_iarf[i][ii]]; + break; + } + } + assert(kk<3); + } + if(!jel || (mesh->tetra[jel].ref != pt1->ref)) { + pt1->bdryref[i] = mesh->tetra[old].bdryref[i]; + if(pt1->bdryref[i]<0) {puts("delone : pbs sd");exit(0); } + } + iadr = (iel-1)*4 + 1; + adjb = &mesh->adja[iadr]; + adjb[i] = adja[i]; + if ( jel ) { + iadr = (jel-1)*4 + 1; + adjb = &mesh->adja[iadr]; + adjb[j] = iel*4 + i; + } + if ( pt1->qual >= declic ) + MMG_kiuput(queue,iel); + + /* internal faces (p1,p2,ip) */ + for (j=0; j<4; j++) { + if ( j != i ) { + m = 0; + for (l=0; l<3; l++) + if ( pt1->v[ MMG_idir[j][l] ] != ip ) { + v[m] = pt1->v[ MMG_idir[j][l] ]; + m++; + } + MMG_hashEdge(mesh,&list->hedg,iel,j,v); + } + } + } + } + } + + /* remove old tetra */ + for (k=1; k<=ilist; k++) { + old = list->tetra[k]; + MMG_delElt(mesh,old); + MMG_kiudel(queue,old); + } + + ppt = &mesh->point[ip]; + ppt->flag = mesh->flag; + return(1); +} + + +/* cavity correction for quality */ +int MMG_correction_ani(pMesh mesh,pSol sol,int ip,pList list,int ilist,int nedep) { + pPoint ppt,p1,p2,p3; + pTetra pt; + double dd,det,nn,eps,eps2,ux,uy,uz,vx,vy,vz,v1,v2,v3; + double *ma,*mb,*mc,*md,mm[6],h1,h2,h3; + int *adja,i,j,ipil,iel,lon,iadr,adj,ib,ic,id,base,ncor; + int vois[4]; + + ppt = &mesh->point[ip]; + if ( ppt->tag & M_UNUSED ) return(ilist); + base = mesh->mark; + lon = ilist; + eps = EPSCON; + eps2 = eps*eps; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ip-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + do { + ipil = lon; + ncor = 0; + + while ( ipil > 0 ) { + iel = list->tetra[ipil]; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + pt = &mesh->tetra[iel]; + +MMG_cas=0; + for (i=0; i<4; i++) { + adj = vois[i]; +MMG_cas = 0; + if ( adj && mesh->tetra[adj].mark == base) continue; + + ib = pt->v[ MMG_idir[i][0] ]; + ic = pt->v[ MMG_idir[i][1] ]; + id = pt->v[ MMG_idir[i][2] ]; + + p1 = &mesh->point[ib]; + p2 = &mesh->point[ic]; + p3 = &mesh->point[id]; + + ux = p2->c[0] - p1->c[0]; + uy = p2->c[1] - p1->c[1]; + uz = p2->c[2] - p1->c[2]; + + vx = p3->c[0] - p1->c[0]; + vy = p3->c[1] - p1->c[1]; + vz = p3->c[2] - p1->c[2]; + + /* volume PABC */ + v1 = uz*vy - uy*vz; + v2 = ux*vz - uz*vx; + v3 = uy*vx - ux*vy; + dd = v1*(ppt->c[0]-p1->c[0]) + v2*(ppt->c[1]-p1->c[1]) \ + + v3*(ppt->c[2]-p1->c[2]); +MMG_cas=1; + //if ( dd < VOLMIN ) break; + /*test sur le volume avec un eps local*/ + h1 = ux*ux + uy*uy + uz*uz; + h2 = vx*vx + vy*vy + vz*vz; + h3 = (p2->c[0] - p3->c[0])*(p2->c[0] - p3->c[0]) + (p2->c[1] - p3->c[1])*(p2->c[1] - p3->c[1]) + + (p2->c[2] - p3->c[2])*(p2->c[2] - p3->c[2]); + if ( dd < VOLMIN*sqrt(h1*h2*h3) ) break; + + /* average metric */ + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) break; + + /* point close to face */ + /*nn = (v1*v1 + v2*v2 + v3*v3);*/ +MMG_cas=2; + nn = mm[0]*v1*v1 + mm[3]*v2*v2 + mm[5]*v3*v3 \ + + 2.0*(mm[1]*v1*v2 + mm[2]*v1*v3 + mm[4]*v2*v3); + /*if ( det*dd*dd*dd*dd*dd*dd < nn * nn * nn * eps2 * eps2 * eps2 ) break;*/ + /*//prendre le min des valeurs propres + eigenv(1,mm,lambda,vv); + det = max(lambda[0],max(lambda[1],lambda[2])); + if ( det*dd*dd < nn * eps2 ) break; + *//*if ( pow(det,1./3.)*dd*dd < nn * eps2 ) break;*/ + if ( det*dd*dd < nn * eps2 ) break; + /*if ( dd*dd < nn * eps2 ) { + printf("en iso : %e %e %e %e\n",dd,nn,dd*dd,nn*eps2); + printf("en iso sqrt : %e %e %e %e\n",dd,nn,dd/sqrt(nn),(sqrt(mm[0]))*(dd/sqrt(nn))); + + dd1 = mm[0]*v1*v1 + mm[3]*v2*v2 + mm[5]*v3*v3 \ + + 2.0*(mm[1]*v1*v2 + mm[2]*v1*v3 + mm[4]*v2*v3); + //len carre = (dd*dd/norm(v1v2v3)^2)*dd1/(norm(v1v2v3)^2 + printf("aniso : %e %e %e %e %e\n",(dd*dd/nn)*dd1/(nn),sqrt(dd*dd*dd1/(nn*sqrt(nn))),det,det*dd*dd,dd1*eps2); + + nn = sqrt(nn); + ph = dd/nn; + v1 /= nn; + v2 /= nn; + v3 /= nn; + xh = ph*v1 + ppt->c[0]; + yh = ph*v2 + ppt->c[1]; + zh = ph*v3 + ppt->c[2]; + + //dist PH dans la met/ + ux = xh - ppt->c[0]; + uy = yh - ppt->c[1]; + uz = zh - ppt->c[2]; + dd = ux*ux + uy*uy + uz*uz; + + dd2 = mm[0]*ux*ux + mm[3]*uy*uy + mm[5]*uz*uz \ + + 2.0*(mm[1]*ux*uy + mm[2]*ux*uz + mm[4]*uy*uz); + if ( dd2 <= 0.0 ) dd2 = 0.0; + + len = sqrt(dd2); + + printf("on trouve len : %e %e %e\n",len,sqrt(eps2)*sqrt(mm[0]),pow(sqrt(eps2)*sqrt(det),1./3.)); + printf("len carre %e %e\n",mm[0]*v1*v1*ph*ph + mm[3]*v2*v2*ph*ph + mm[5]*v3*v3*ph*ph,dd2); + exit(0); + break; + }*/ +MMG_cas=0; + } + if ( i < 4 ) { + if ( ipil <= nedep ) return(0); + /* remove iel from list */ + pt->mark = base-1; + list->tetra[ipil] = list->tetra[lon]; + lon--; + ncor = 1; + break; + } + else + ipil--; + } + } + while ( ncor > 0 && lon >= nedep ); + + return(lon); +} + + +/* cavity correction for quality */ +int MMG_correction_iso(pMesh mesh,int ip,pList list,int ilist,int nedep) { + pPoint ppt,p1,p2,p3; + pTetra pt; + double dd,nn,eps,eps2,ux,uy,uz,vx,vy,vz,v1,v2,v3; + int *adja,i,ipil,iel,lon,iadr,adj,ib,ic,id,base,ncor; + int vois[4]; + + ppt = &mesh->point[ip]; + if ( ppt->tag & M_UNUSED ) return(ilist); + base = mesh->mark; + lon = ilist; + eps = EPSCON; + eps2 = eps*eps; + do { + ipil = lon; + ncor = 0; + + while ( ipil > 0 ) { + iel = list->tetra[ipil]; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0] >> 2; + vois[1] = adja[1] >> 2; + vois[2] = adja[2] >> 2; + vois[3] = adja[3] >> 2; + pt = &mesh->tetra[iel]; +MMG_cas=0; + for (i=0; i<4; i++) { + adj = vois[i]; +MMG_cas = 0; + if ( adj && mesh->tetra[adj].mark == base ) continue; + + ib = pt->v[ MMG_idir[i][0] ]; + ic = pt->v[ MMG_idir[i][1] ]; + id = pt->v[ MMG_idir[i][2] ]; + + p1 = &mesh->point[ib]; + p2 = &mesh->point[ic]; + p3 = &mesh->point[id]; + + ux = p2->c[0] - p1->c[0]; + uy = p2->c[1] - p1->c[1]; + uz = p2->c[2] - p1->c[2]; + + vx = p3->c[0] - p1->c[0]; + vy = p3->c[1] - p1->c[1]; + vz = p3->c[2] - p1->c[2]; + + /* volume PABC */ + v1 = uz*vy - uy*vz; + v2 = ux*vz - uz*vx; + v3 = uy*vx - ux*vy; + dd = v1*(ppt->c[0]-p1->c[0]) + v2*(ppt->c[1]-p1->c[1]) \ + + v3*(ppt->c[2]-p1->c[2]); +MMG_cas=1; +//printf("on trouve vol %e <? %e\n",dd,VOLMIN); + if ( dd < VOLMIN ) break; + + /* point close to face */ + nn = (v1*v1 + v2*v2 + v3*v3); +MMG_cas=2; +//printf("on trouve close ? %e %e\n",dd*dd,nn*eps2); + if ( dd*dd < nn * eps2 ) break; +MMG_cas=0; + } + if ( i < 4 ) { + if ( ipil <= nedep ) {/*printf("on veut tout retirer ? %d %d\n",ipil,nedep);*/return(0); } + /* remove iel from list */ + pt->mark = base-1; + list->tetra[ipil] = list->tetra[lon]; + lon--; + ncor = 1; + break; + } + else + ipil--; + } + } + while ( ncor > 0 && lon >= nedep ); + + return(lon); +} + + +/* mark elements in cavity */ +int MMG_cavity_ani(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon) { + pPoint ppt; + pTetra pt,pt1,ptc; + double c[3],eps,dd,ray,ux,uy,uz,crit; + double *mj,*mp,ct[12]; + int *adja,*adjb,k,adj,adi,voy,i,j,ia,ilist,ipil,jel,iadr,base; + int vois[4],l; + + if ( lon < 1 ) return(0); + ppt = &mesh->point[ip]; + if ( ppt->tag & M_UNUSED ) return(0); + + for (k=1; k<=lon; k++) + list->tetra[k] = list->tetra[k] / 6; + + /* grow cavity by adjacency */ + base = mesh->mark; + eps = EPSRAD * EPSRAD; + ilist = lon; + ipil = 1; + iadr = (ip-1)*sol->offset + 1; + mp = &sol->met[iadr]; + + do { + jel = list->tetra[ipil]; + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0]; + vois[1] = adja[1]; + vois[2] = adja[2]; + vois[3] = adja[3]; + ptc = &mesh->tetra[jel]; + + for (i=0; i<4; i++) { + adj = vois[i] >> 2; + voy = vois[i] % 4; + if ( !adj ) continue; + pt = &mesh->tetra[adj]; + /* boundary face */ + if ( pt->mark == base || pt->ref != ptc->ref ) continue; + for (j=0,l=0; j<4; j++,l+=3) { + memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double)); + } + + + /* Delaunay kernel */ + if ( !MMG_cenrad_ani(mesh,ct,mp,c,&ray) ) continue; + + ux = ppt->c[0] - c[0]; + uy = ppt->c[1] - c[1]; + uz = ppt->c[2] - c[2]; + dd = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + crit = eps * ray; + if ( dd > crit ) continue; + + /* mixed metrics */ + crit = sqrt(dd/ray); + for (j=0; j<4; j++) { + ia = pt->v[j]; + iadr = (ia-1)*sol->offset + 1; + mj = &sol->met[iadr]; + if ( !MMG_cenrad_ani(mesh,ct,mj,c,&ray) ) continue; + ux = ppt->c[0] - c[0]; + uy = ppt->c[1] - c[1]; + uz = ppt->c[2] - c[2]; + dd = mj[0]*ux*ux + mj[3]*uy*uy + mj[5]*uz*uz \ + + 2.0*(mj[1]*ux*uy + mj[2]*ux*uz + mj[4]*uy*uz); + crit += sqrt(dd/ray); + } + crit *= EPSRAD; + if ( crit > 5.0 ) continue; + + /* lost face(s) */ + iadr = (adj-1)*4 + 1; + adjb = &mesh->adja[iadr]; + + for (j=0; j<4; j++) { + if ( j == voy ) continue; + adi = adjb[j] >> 2; + if ( !adi ) continue; + pt1 = &mesh->tetra[adi]; + if ( pt1->mark == base && adi != jel ) { + if ( !adi || pt1->ref != mesh->tetra[adi].ref ) break; + } + } + /* store tetra */ + if ( j == 4 ) { + pt->mark = base; + ++ilist; + list->tetra[ilist] = adj; + } + } + if ( ilist > LONMAX - 3 ) return(-1); + ++ipil; + } + while ( ipil <= ilist ); + + /* global overflow */ + if ( mesh->ne + 2*ilist >= mesh->nemax ) + ilist = -ilist; + else + ilist = MMG_correction_ani(mesh,sol,ip,list,ilist,lon); + +if(MMG_cas==1) MMG_nvol++; +else if(MMG_cas==2 || MMG_cas>20) { + MMG_npuiss++; + if(MMG_cas>20) MMG_npres++; +} + + return(ilist); +} + + +int MMG_cavity_iso(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon) { + pPoint ppt; + pTetra pt,pt1,ptc; + double c[3],crit,dd,eps,ray,ct[12]; + int *adja,*adjb,k,adj,adi,voy,i,j,ilist,ipil,jel,iadr,base; + int vois[4],l; + int tref; + + if ( lon < 1 ) return(0); + ppt = &mesh->point[ip]; + if ( ppt->tag & M_UNUSED ) return(0); + + tref = mesh->tetra[list->tetra[1]/6].ref; +#warning remove this test + for (k=1; k<=lon; k++) + if(tref!=mesh->tetra[list->tetra[k]/6].ref) + printf("pbs coquil %d %d tet %d\n",tref,mesh->tetra[list->tetra[k]/6].ref,list->tetra[k]/6); + + for (k=1; k<=lon; k++) + list->tetra[k] = list->tetra[k] / 6; + + /* grow cavity by adjacency */ + base = mesh->mark; + eps = EPSRAD*EPSRAD; + ilist = lon; + ipil = 1; + + do { + jel = list->tetra[ipil]; + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + vois[0] = adja[0]; + vois[1] = adja[1]; + vois[2] = adja[2]; + vois[3] = adja[3]; + ptc = &mesh->tetra[jel]; + + for (i=0; i<4; i++) { + adj = vois[i] >> 2; + voy = vois[i] % 4; + if ( !adj ) continue; + pt = &mesh->tetra[adj]; + /* boundary face */ + if ( pt->mark == base || pt->ref != ptc->ref ) continue; + + for (j=0,l=0; j<4; j++,l+=3) { + memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double)); + } + + if ( !MMG_cenrad_iso(mesh,ct,c,&ray) ) continue; + crit = eps * ray; + + /* Delaunay criterion */ + dd = (ppt->c[0] - c[0]) * (ppt->c[0] - c[0]) \ + + (ppt->c[1] - c[1]) * (ppt->c[1] - c[1]) \ + + (ppt->c[2] - c[2]) * (ppt->c[2] - c[2]); + if ( dd > crit ) continue; + + /* lost face(s) */ + iadr = (adj-1)*4 + 1; + adjb = &mesh->adja[iadr]; + + for (j=0; j<4; j++) { + if ( j == voy ) continue; + adi = adjb[j] >> 2; + if ( !adi ) continue; + pt1 = &mesh->tetra[adi]; + if ( pt1->mark == base && adi != jel ) { + if ( !adi || pt1->ref != mesh->tetra[adi].ref ) break; + } + } + /* store tetra */ + if ( j == 4 ) { + pt->mark = base; + ++ilist; + list->tetra[ilist] = adj; + } + } + if ( ilist > LONMAX - 3 ) return(-1); + ++ipil; + } + while ( ipil <= ilist ); + /* global overflow */ + if ( mesh->ne + 2*ilist >= mesh->nemax ) + ilist = -ilist; + else + ilist = MMG_correction_iso(mesh,ip,list,ilist,lon); + +if(MMG_cas==1) MMG_nvol++; +else if(MMG_cas==2 || MMG_cas>20) { + MMG_npuiss++; + if(MMG_cas>20) MMG_npres++; +} + + return(ilist); +} diff --git a/contrib/mmg3d/build/sources/eigenv.c b/contrib/mmg3d/build/sources/eigenv.c new file mode 100644 index 0000000000..8a75bd32b2 --- /dev/null +++ b/contrib/mmg3d/build/sources/eigenv.c @@ -0,0 +1,666 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include <stdio.h> +#include <string.h> +#include <math.h> + +/* seeking 1.e-05 accuracy */ +#define EPSD 1.e-15 +#define EPSD2 1.e-10 +#define EPS6 5.e-06 +#define EPS 1.e-06 +#define EPSX2 2.e-06 +#define MAXTOU 50 + +/* check if numbers are equal */ +#define egal(x,y) ( \ + ( ((x) == 0.0f) ? (fabs(y) < EPS) : \ + ( ((y) == 0.0f) ? (fabs(x) < EPS) : \ + (fabs((x)-(y)) / (fabs(x) + fabs(y)) < EPSX2) ) ) ) + + +static double Id[3][3] = { + {1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0}, + {0.0, 0.0, 1.0} }; + + +/* find root(s) of polynomial: P(x)= x^3+bx^2+cx+d + return 1: 3 roots, 2: 2 roots, 3: 1 root */ +static int newton3(double p[4],double x[3]) { + double b,c,d,da,db,dc,epsd; + double delta,fx,dfx,dxx; + double fdx0,fdx1,dx0,dx1,x1,x2; + int it,n; + + /* coeffs polynomial, a=1 */ + b = p[2]; + c = p[1]; + d = p[0]; + n = 1; + + /* 1st derivative of f */ + da = 3.0; + db = 2.0*b; + + /* solve 2nd order eqn */ + delta = db*db - 4.0*da*c; + epsd = db*db*EPSD2; + + /* inflexion (f'(x)=0, x=-b/2a) */ + x1 = -db / 6.0f; + + n = 1; + if ( delta > epsd ) { + delta = sqrt(delta); + dx0 = (-db + delta) / 6.0; + dx1 = (-db - delta) / 6.0; + /* Horner */ + fdx0 = d + dx0*(c+dx0*(b+dx0)); + fdx1 = d + dx1*(c+dx1*(b+dx1)); + + if ( fabs(fdx0) < EPSD ) { + /* dx0: double root, compute single root */ + n = 2; + x[0] = dx0; + x[1] = dx0; + x[2] = -b - 2.0*dx0; + /* check if P(x) = 0 */ + fx = d + x[2]*(c+x[2]*(b+x[2])); + if ( fabs(fx) > EPSD2 ) { +#ifdef DEBUG + fprintf(stderr," ## ERR 9100, newton3: fx= %E\n",fx); +#endif + return(0); + } + return(n); + } + else if ( fabs(fdx1) < EPSD ) { + /* dx1: double root, compute single root */ + n = 2; + x[0] = dx1; + x[1] = dx1; + x[2] = -b - 2.0*dx1; + /* check if P(x) = 0 */ + fx = d + x[2]*(c+x[2]*(b+x[2])); + if ( fabs(fx) > EPSD2 ) { +#ifdef DEBUG + fprintf(stderr," ## ERR 9100, newton3: fx= %E\n",fx); +#endif + return(0); + } + return(n); + } + } + + else if ( fabs(delta) < epsd ) { + /* triple root */ + n = 3; + x[0] = x1; + x[1] = x1; + x[2] = x1; + /* check if P(x) = 0 */ + fx = d + x[0]*(c+x[0]*(b+x[0])); + if ( fabs(fx) > EPSD2 ) { +#ifdef DEBUG + fprintf(stderr," ## ERR 9100, newton3: fx= %E\n",fx); +#endif + return(0); + } + return(n); + } + + else { +#ifdef DEBUG + fprintf(stderr," ## ERR 9101, newton3: no real roots\n"); +#endif + return(0); + } + + /* Newton method: find one root (middle) + starting point: P"(x)=0 */ + x1 = -b / 3.0; + dfx = c + b*x1; + fx = d + x1*(c -2.0*x1*x1); + it = 0; + do { + x2 = x1 - fx / dfx; + fx = d + x2*(c+x2*(b+x2)); + if ( fabs(fx) < EPSD ) { + x[0] = x2; + break; + } + dfx = c + x2*(db + da*x2); + + /* check for break-off condition */ + dxx = fabs((x2-x1) / x2); + if ( dxx < 1.0e-10 ) { + x[0] = x2; + if ( fabs(fx) > EPSD2 ) { + fprintf(stderr," ## ERR 9102, newton3, no root found (fx %E).\n",fx); + return(0); + } + break; + } + else + x1 = x2; + } + while ( ++it < MAXTOU ); + + if ( it == MAXTOU ) { + x[0] = x1; + fx = d + x1*(c+(x1*(b+x1))); + if ( fabs(fx) > EPSD2 ) { + fprintf(stderr," ## ERR 9102, newton3, no root found (fx %E).\n",fx); + return(0); + } + } + + /* solve 2nd order equation + P(x) = (x-sol(1))* (x^2+bb*x+cc) */ + db = b + x[0]; + dc = c + x[0]*db; + delta = db*db - 4.0*dc; + + if ( delta <= 0.0 ) { + fprintf(stderr," ## ERR 9103, newton3, det = 0.\n"); + return(0); + } + + delta = sqrt(delta); + x[1] = 0.5 * (-db+delta); + x[2] = 0.5 * (-db-delta); + +#ifdef DEBUG + /* check for root accuracy */ + fx = d + x[1]*(c+x[1]*(b+x[1])); + if ( fabs(fx) > EPSD2 ) { + fprintf(stderr," ## ERR 9104, newton3: fx= %E x= %E\n",fx,x[1]); + return(0); + } + fx = d + x[2]*(c+x[2]*(b+x[2])); + if ( fabs(fx) > EPSD2 ) { + fprintf(stderr," ## ERR 9104, newton3: fx= %E x= %E\n",fx,x[2]); + return(0); + } + } +#endif + + return(n); +} + + +/* find eigenvalues and vectors of a 3x3 symmetric definite + * positive matrix + * return order of eigenvalues (1,2,3) or 0 if failed */ +int eigenv(int symmat,double *mat,double lambda[3],double v[3][3]) { + double a11,a12,a13,a21,a22,a23,a31,a32,a33; + double aa,bb,cc,dd,ee,ii,vx1[3],vx2[3],vx3[3],dd1,dd2,dd3; + double maxd,maxm,valm,p[4],w1[3],w2[3],w3[3]; + int k,n; + + /* default */ + memcpy(v,Id,9*sizeof(double)); + if ( symmat ) { + lambda[0] = (double)mat[0]; + lambda[1] = (double)mat[3]; + lambda[2] = (double)mat[5]; + + maxm = fabs(mat[0]); + for (k=1; k<6; k++) { + valm = fabs(mat[k]); + if ( valm > maxm ) maxm = valm; + } + /* single float accuracy */ + if ( maxm < EPS6 ) return(1); + + /* normalize matrix */ + dd = 1.0 / maxm; + a11 = mat[0] * dd; + a12 = mat[1] * dd; + a13 = mat[2] * dd; + a22 = mat[3] * dd; + a23 = mat[4] * dd; + a33 = mat[5] * dd; + + /* diagonal matrix */ + maxd = fabs(a12); + valm = fabs(a13); + if ( valm > maxd ) maxd = valm; + valm = fabs(a23); + if ( valm > maxd ) maxd = valm; + if ( maxd < EPSD ) return(1); + + a21 = a12; + a31 = a13; + a32 = a23; + + /* build characteristic polynomial + P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */ + aa = a11*a22; + bb = a23*a32; + cc = a12*a21; + dd = a13*a31; + p[0] = a11*bb + a33*(cc-aa) + a22*dd -2.0*a12*a13*a23; + p[1] = a11*(a22 + a33) + a22*a33 - bb - cc - dd; + p[2] = -a11 - a22 - a33; + p[3] = 1.0; + } + else { + lambda[0] = (double)mat[0]; + lambda[1] = (double)mat[4]; + lambda[2] = (double)mat[8]; + + maxm = fabs(mat[0]); + for (k=1; k<9; k++) { + valm = fabs(mat[k]); + if ( valm > maxm ) maxm = valm; + } + if ( maxm < EPS6 ) return(1); + + /* normalize matrix */ + dd = 1.0 / maxm; + a11 = mat[0] * dd; + a12 = mat[1] * dd; + a13 = mat[2] * dd; + a21 = mat[3] * dd; + a22 = mat[4] * dd; + a23 = mat[5] * dd; + a31 = mat[6] * dd; + a32 = mat[7] * dd; + a33 = mat[8] * dd; + + /* diagonal matrix */ + maxd = fabs(a12); + valm = fabs(a13); + if ( valm > maxd ) maxd = valm; + valm = fabs(a23); + if ( valm > maxd ) maxd = valm; + valm = fabs(a21); + if ( valm > maxd ) maxd = valm; + valm = fabs(a31); + if ( valm > maxd ) maxd = valm; + valm = fabs(a32); + if ( valm > maxd ) maxd = valm; + if ( maxd < EPSD ) return(1); + + /* build characteristic polynomial + P(X) = X^3 - trace X^2 + (somme des mineurs)X - det = 0 */ + aa = a22*a33 - a23*a32; + bb = a23*a31 - a21*a33; + cc = a21*a32 - a31*a22; + ee = a11*a33 - a13*a31; + ii = a11*a22 - a12*a21; + + p[0] = -a11*aa - a12*bb - a13*cc; + p[1] = aa + ee + ii; + p[2] = -a11 - a22 - a33; + p[3] = 1.0; + } + + /* solve polynomial (find roots using newton) */ + n = newton3(p,lambda); + if ( n <= 0 ) return(0); + + /* compute eigenvectors: + an eigenvalue belong to orthogonal of Im(A-lambda*Id) */ + v[0][0] = 1.0; v[0][1] = v[0][2] = 0.0; + v[1][1] = 1.0; v[1][0] = v[1][2] = 0.0; + v[2][2] = 1.0; v[2][0] = v[2][1] = 0.0; + + w1[1] = a12; w1[2] = a13; + w2[0] = a21; w2[2] = a23; + w3[0] = a31; w3[1] = a32; + + if ( n == 1 ) { + /* vk = crsprd(wi,wj) */ + for (k=0; k<3; k++) { + w1[0] = a11 - lambda[k]; + w2[1] = a22 - lambda[k]; + w3[2] = a33 - lambda[k]; + + /* cross product vectors in (Im(A-lambda(i) Id) ortho */ + vx1[0] = w1[1]*w3[2] - w1[2]*w3[1]; + vx1[1] = w1[2]*w3[0] - w1[0]*w3[2]; + vx1[2] = w1[0]*w3[1] - w1[1]*w3[0]; + dd1 = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2]; + + vx2[0] = w1[1]*w2[2] - w1[2]*w2[1]; + vx2[1] = w1[2]*w2[0] - w1[0]*w2[2]; + vx2[2] = w1[0]*w2[1] - w1[1]*w2[0]; + dd2 = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2]; + + vx3[0] = w2[1]*w3[2] - w2[2]*w3[1]; + vx3[1] = w2[2]*w3[0] - w2[0]*w3[2]; + vx3[2] = w2[0]*w3[1] - w2[1]*w3[0]; + dd3 = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2]; + + /* find vector of max norm */ + if ( dd1 > dd2 ) { + if ( dd1 > dd3 ) { + dd1 = 1.0 / sqrt(dd1); + v[k][0] = vx1[0] * dd1; + v[k][1] = vx1[1] * dd1; + v[k][2] = vx1[2] * dd1; + } + else { + dd3 = 1.0 / sqrt(dd3); + v[k][0] = vx3[0] * dd3; + v[k][1] = vx3[1] * dd3; + v[k][2] = vx3[2] * dd3; + } + } + else { + if ( dd2 > dd3 ) { + dd2 = 1.0 / sqrt(dd2); + v[k][0] = vx2[0] * dd2; + v[k][1] = vx2[1] * dd2; + v[k][2] = vx2[2] * dd2; + } + else { + dd3 = 1.0 / sqrt(dd3); + v[k][0] = vx3[0] * dd3; + v[k][1] = vx3[1] * dd3; + v[k][2] = vx3[2] * dd3; + } + } + } + } + + /* (vp1,vp2) double, vp3 simple root */ + else if ( n == 2 ) { + w1[0] = a11 - lambda[2]; + w2[1] = a22 - lambda[2]; + w3[2] = a33 - lambda[2]; + + /* cross product */ + vx1[0] = w1[1]*w3[2] - w1[2]*w3[1]; + vx1[1] = w1[2]*w3[0] - w1[0]*w3[2]; + vx1[2] = w1[0]*w3[1] - w1[1]*w3[0]; + dd1 = vx1[0]*vx1[0] + vx1[1]*vx1[1] + vx1[2]*vx1[2]; + + vx2[0] = w1[1]*w2[2] - w1[2]*w2[1]; + vx2[1] = w1[2]*w2[0] - w1[0]*w2[2]; + vx2[2] = w1[0]*w2[1] - w1[1]*w2[0]; + dd2 = vx2[0]*vx2[0] + vx2[1]*vx2[1] + vx2[2]*vx2[2]; + + vx3[0] = w2[1]*w3[2] - w2[2]*w3[1]; + vx3[1] = w2[2]*w3[0] - w2[0]*w3[2]; + vx3[2] = w2[0]*w3[1] - w2[1]*w3[0]; + dd3 = vx3[0]*vx3[0] + vx3[1]*vx3[1] + vx3[2]*vx3[2]; + + /* find vector of max norm */ + if ( dd1 > dd2 ) { + if ( dd1 > dd3 ) { + dd1 = 1.0 / sqrt(dd1); + v[2][0] = vx1[0] * dd1; + v[2][1] = vx1[1] * dd1; + v[2][2] = vx1[2] * dd1; + } + else { + dd3 = 1.0 / sqrt(dd3); + v[2][0] = vx3[0] * dd3; + v[2][1] = vx3[1] * dd3; + v[2][2] = vx3[2] * dd3; + } + } + else { + if ( dd2 > dd3 ) { + dd2 = 1.0 / sqrt(dd2); + v[2][0] = vx2[0] * dd2; + v[2][1] = vx2[1] * dd2; + v[2][2] = vx2[2] * dd2; + } + else { + dd3 = 1.0 / sqrt(dd3); + v[2][0] = vx3[0] * dd3; + v[2][1] = vx3[1] * dd3; + v[2][2] = vx3[2] * dd3; + } + } + + /* compute v1 and v2 in Im(A-vp3*Id) */ + dd1 = w1[0]*w1[0] + w1[1]*w1[1] + w1[2]*w1[2]; + dd2 = w2[0]*w2[0] + w2[1]*w2[1] + w2[2]*w2[2]; + if ( dd1 > dd2 ) { + dd1 = 1.0 / sqrt(dd1); + v[0][0] = w1[0]*dd1; + v[0][1] = w1[1]*dd1; + v[0][2] = w1[2]*dd1; + } + else { + dd2 = 1.0 / sqrt(dd2); + v[0][0] = w2[0]*dd2; + v[0][1] = w2[1]*dd2; + v[0][2] = w2[2]*dd2; + } + + /* 3rd vector orthogonal */ + v[1][0] = v[2][1]*v[0][2] - v[2][2]*v[0][1]; + v[1][1] = v[2][2]*v[0][0] - v[2][0]*v[0][2]; + v[1][2] = v[2][0]*v[0][1] - v[2][1]*v[0][0]; + dd1 = v[1][0]*v[1][0] + v[1][1]*v[1][1] + v[1][2]*v[1][2]; + dd1 = 1.0 / sqrt(dd1); + v[1][0] *= dd1; + v[1][1] *= dd1; + v[1][2] *= dd1; + } + + lambda[0] *= maxm; + lambda[1] *= maxm; + lambda[2] *= maxm; + + /* check accuracy */ + /*------------------------------------------------------------------- + if ( ddebug && symmat ) { + double err,tmpx,tmpy,tmpz; + float m[6]; + int i,j; + + k = 0; + for (i=0; i<3; i++) + for (j=i; j<3; j++) + m[k++] = lambda[0]*v[i][0]*v[j][0] + + lambda[1]*v[i][1]*v[j][1] + + lambda[2]*v[i][2]*v[j][2]; + err = fabs(mat[0]-m[0]); + for (i=1; i<6; i++) + if ( fabs(m[i]-mat[i]) > err ) err = fabs(m[i]-mat[i]); + + if ( err > 1.e03*maxm ) { + printf("\nProbleme eigenv3: err= %f\n",err*maxm); + printf("mat depart :\n"); + printf("%13.6f %13.6f %13.6f\n",mat[0],mat[1],mat[2]); + printf("%13.6f %13.6f %13.6f\n",mat[1],mat[3],mat[4]); + printf("%13.6f %13.6f %13.6f\n",mat[2],mat[4],mat[5]); + printf("mat finale :\n"); + printf("%13.6f %13.6f %13.6f\n",m[0],m[1],m[2]); + printf("%13.6f %13.6f %13.6f\n",m[1],m[3],m[4]); + printf("%13.6f %13.6f %13.6f\n",m[2],m[4],m[5]); + printf("lambda : %f %f %f\n",lambda[0],lambda[1],lambda[2]); + printf(" ordre %d\n",n); + printf("\nOrtho:\n"); + printf("v1.v2 = %.14f\n", + v[0][0]*v[1][0]+v[0][1]*v[1][1]+ v[0][2]*v[1][2]); + printf("v1.v3 = %.14f\n", + v[0][0]*v[2][0]+v[0][1]*v[2][1]+ v[0][2]*v[2][2]); + printf("v2.v3 = %.14f\n", + v[1][0]*v[2][0]+v[1][1]*v[2][1]+ v[1][2]*v[2][2]); + + printf("Consistency\n"); + for (i=0; i<3; i++) { + tmpx = v[0][i]*m[0] + v[1][i]*m[1] + + v[2][i]*m[2] - lambda[i]*v[0][i]; + tmpy = v[0][i]*m[1] + v[1][i]*m[3] + + v[2][i]*m[4] - lambda[i]*v[1][i]; + tmpz = v[0][i]*m[2] + v[1][i]*m[4] + + v[2][i]*m[5] - lambda[i]*v[2][i]; + printf(" Av %d - lambda %d *v %d = %f %f %f\n", + i,i,i,tmpx,tmpy,tmpz); + + printf("w1 %f %f %f\n",w1[0],w1[1],w1[2]); + printf("w2 %f %f %f\n",w2[0],w2[1],w2[2]); + printf("w3 %f %f %f\n",w3[0],w3[1],w3[2]); + } + exit(1); + } + } + -------------------------------------------------------------------*/ + + return(n); +} + + +/* eigen value + vector extraction */ +int eigen2(double *mm,double *lambda,double vp[2][2]) { + double m[3],dd,a1,xn,ddeltb,rr1,rr2,ux,uy; + + /* init */ + ux = 1.0; + uy = 0.0; + + /* normalize */ + memcpy(m,mm,3*sizeof(double)); + xn = fabs(m[0]); + if ( fabs(m[1]) > xn ) xn = fabs(m[1]); + if ( fabs(m[2]) > xn ) xn = fabs(m[2]); + if ( xn < EPSD2 ) { + lambda[0] = lambda[1] = 0.0; + vp[0][0] = 1.0; + vp[0][1] = 0.0; + vp[1][0] = 0.0; + vp[1][1] = 1.0; + return(1); + } + xn = 1.0 / xn; + m[0] *= xn; + m[1] *= xn; + m[2] *= xn; + + if ( egal(m[1],0.0) ) { + rr1 = m[0]; + rr2 = m[2]; + goto vect; + } + + /* eigenvalues of jacobian */ + a1 = -(m[0] + m[2]); + ddeltb = a1*a1 - 4.0 * (m[0]*m[2] - m[1]*m[1]); + + if ( ddeltb < 0.0 ) { + fprintf(stderr," Delta: %f\n",ddeltb); + ddeltb = 0.0; + } + ddeltb = sqrt(ddeltb); + + if ( fabs(a1) < EPS ) { + rr1 = 0.5 * sqrt(ddeltb); + rr2 = -rr1; + } + else if ( a1 < 0.0 ) { + rr1 = 0.5 * (-a1 + ddeltb); + rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1; + } + else if ( a1 > 0.0 ) { + rr1 = 0.5 * (-a1 - ddeltb); + rr2 = (-m[1]*m[1] + m[0]*m[2]) / rr1; + } + else { + rr1 = 0.5 * ddeltb; + rr2 = -rr1; + } + +vect: + xn = 1.0 / xn; + lambda[0] = rr1 * xn; + lambda[1] = rr2 * xn; + + /* eigenvectors */ + a1 = m[0] - rr1; + if ( fabs(a1)+fabs(m[1]) < EPS ) { + if (fabs(lambda[1]) < fabs(lambda[0]) ) { + ux = 1.0; + uy = 0.0; + } + else { + ux = 0.0; + uy = 1.0; + } + } + else if ( fabs(a1) < fabs(m[1]) ) { + ux = 1.0; + uy = -a1 / m[1]; + } + else if ( fabs(a1) > fabs(m[1]) ) { + ux = -m[1] / a1; + uy = 1.0; + } + else if ( fabs(lambda[1]) > fabs(lambda[0]) ) { + ux = 0.0; + uy = 1.0; + } + else { + ux = 1.0; + uy = 0.0; + } + + dd = sqrt(ux*ux + uy*uy); + dd = 1.0 / dd; + if ( fabs(lambda[0]) > fabs(lambda[1]) ) { + vp[0][0] = ux * dd; + vp[0][1] = uy * dd; + } + else { + vp[0][0] = uy * dd; + vp[0][1] = -ux * dd; + } + + /* orthogonal vector */ + vp[1][0] = -vp[0][1]; + vp[1][1] = vp[0][0]; + + return(1); +} diff --git a/contrib/mmg3d/build/sources/eigenv.h b/contrib/mmg3d/build/sources/eigenv.h new file mode 100644 index 0000000000..2f2d806a0d --- /dev/null +++ b/contrib/mmg3d/build/sources/eigenv.h @@ -0,0 +1,47 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +int eigenv(int symmat,double *mat,double lambda[3],double v[3][3]); +int eigen2(double *mm,double *lambda,double vp[2][2]); diff --git a/contrib/mmg3d/build/sources/hash.c b/contrib/mmg3d/build/sources/hash.c new file mode 100644 index 0000000000..1fa340f024 --- /dev/null +++ b/contrib/mmg3d/build/sources/hash.c @@ -0,0 +1,551 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define KA 31 +#define KB 57 +#define KC 79 + +#define KTA 7 +#define KTB 11 +#define KTC 13 + + + +/* local data structures */ +typedef struct { + int min,max,sum,iel,nxt; +} hface; + +typedef struct { + int size,hnxt,nhmax; + hface *item; +} Hface; + + +int MMG_hashTetra(pMesh mesh) { + pTetra pt,pt1; + int k,kk,pp,l,ll,mins,mins1,maxs,maxs1,sum,sum1,iadr; + int *hcode,*link,hsize; + long int inival; + unsigned char i,ii,i1,i2,i3; + unsigned int key; + + /* default */ + if ( abs(mesh->info.imprim) > 5 ) { + fprintf(stdout," ** SETTING ADJACENCIES\n"); + fflush(stdout); + } + /* memory alloc */ + hcode = (int*)M_calloc(mesh->nemax+1,sizeof(int),"hash"); + assert(hcode); + link = mesh->adja; + hsize = mesh->ne; + + /* init */ + inival = 2147483647; + for (k=0; k<=mesh->ne; k++) + hcode[k] = -inival; + /* build hash table */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + for (i=0; i<4; i++) { + i1 = MMG_idir[i][0]; + i2 = MMG_idir[i][1]; + i3 = MMG_idir[i][2]; + mins = M_MIN(pt->v[i1],pt->v[i2]); + mins = M_MIN(mins,pt->v[i3]); + maxs = M_MAX(pt->v[i1],pt->v[i2]); + maxs = M_MAX(maxs,pt->v[i3]); + + /* compute key */ + sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; + key = KA*mins + KB*maxs + KC*sum; + key = key % hsize + 1; + + /* insert */ + iadr = 4*(k-1) + i+1; + link[iadr] = hcode[key]; + hcode[key] = -iadr; + } + } + + /* set adjacency */ + for (l=4*mesh->ne; l>0; l--) { + if ( link[l] >= 0 ) continue; + k = ((l-1) >> 2) + 1; + i = (l-1) % 4; + i1 = MMG_idir[i][0]; + i2 = MMG_idir[i][1]; + i3 = MMG_idir[i][2]; + pt = &mesh->tetra[k]; + + sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; + mins = M_MIN(pt->v[i1],pt->v[i2]); + mins = M_MIN(mins,pt->v[i3]); + maxs = M_MAX(pt->v[i1],pt->v[i2]); + maxs = M_MAX(maxs,pt->v[i3]); + + /* accross link */ + ll = -link[l]; + pp = 0; + link[l] = 0; + while ( ll != inival ) { + kk = ((ll-1) >> 2) + 1; + ii = (ll-1) % 4; + i1 = MMG_idir[ii][0]; + i2 = MMG_idir[ii][1]; + i3 = MMG_idir[ii][2]; + pt1 = &mesh->tetra[kk]; + sum1 = pt1->v[i1] + pt1->v[i2] + pt1->v[i3]; + if ( sum1 == sum ) { + mins1 = M_MIN(pt1->v[i1],pt1->v[i2]); + mins1 = M_MIN(mins1,pt1->v[i3]); + if ( mins1 == mins ) { + maxs1 = M_MAX(pt1->v[i1],pt1->v[i2]); + maxs1 = M_MAX(maxs1,pt1->v[i3]); + if ( maxs1 == maxs ) { + /* adjacent found */ + if ( pp != 0 ) link[pp] = link[ll]; + link[l] = 4*kk + ii; + link[ll]= 4*k + i; + break; + } + } + } + pp = ll; + ll = -link[ll]; + } + } + + M_free(hcode); + return(1); +} + + + +/* hash mesh edge v[0],v[1] (face i of iel) */ +int MMG_hashEdge(pMesh mesh,pHedge hash,int iel,int i,int *v) { + int *adja,iadr,jel,j,key,mins,maxs; + hedge *ha; + + /* compute key */ + if ( v[0] < v[1] ) { + mins = v[0]; + maxs = v[1]; + } + else { + mins = v[1]; + maxs = v[0]; + } + key = KTA*mins + KTB*maxs; + key = key % hash->size; + ha = &hash->item[key]; + + if ( ha->min ) { + /* identical face */ + if ( ha->min == mins && ha->max == maxs ) { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[i] = ha->iel; + + jel = ha->iel >> 2; + j = ha->iel % 4; + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[j] = iel*4 + i; + return(1); + } + else + while ( ha->nxt && ha->nxt < hash->nhmax ) { + ha = &hash->item[ha->nxt]; + if ( ha->min == mins && ha->max == maxs ) { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[i] = ha->iel; + + jel = ha->iel >> 2; + j = ha->iel % 4; + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[j] = iel*4 + i; + return(1); + } + } + ha->nxt = hash->hnxt; + ha = &hash->item[hash->hnxt]; + ++hash->hnxt; + if ( hash->hnxt == hash->nhmax ) { + fprintf(stdout," ## Memory alloc problem (edge): %d\n",hash->nhmax); + return(0); + } + } + + /* insert */ + ha->min = mins; + ha->max = maxs; + ha->iel = iel*4 + i; + ha->nxt = 0; + + return(1); +} + + +int MMG_inEdge(pHedge hash,int *v,int *iel,int *ia) { + int key,mins,maxs; + hedge *ha; + + /* compute key */ + if ( v[0] < v[1] ) { + mins = v[0]; + maxs = v[1]; + } + else { + mins = v[1]; + maxs = v[0]; + } + key = KA*mins + KB*maxs; + key = key % hash->size; + + ha = &hash->item[key]; + + if ( !ha->min ) return(0); + else if ( ha->min == mins && ha->max == maxs ) { + *iel = ha->iel / 6; + *ia = ha->iel % 6; + return(1); + } + else if ( ha->nxt ) { + do { + ha = &hash->item[ha->nxt]; + if ( ha->min == mins && ha->max == maxs ) { + *iel = ha->iel / 6; + *ia = ha->iel % 6; + return(1); + } + } + while ( ha->nxt && ha->nxt < hash->nhmax ); + } + + return(0); +} + + +/* hash triangles and return + iel: face stored, 0 problem */ +int MMG_hashFace(Hface *hash,int iel,int *v) { + int key,mins,maxs,sum; + hface *ht; + + mins = M_MIN(v[0],v[1]); + mins = M_MIN(mins,v[2]); + maxs = M_MAX(v[0],v[1]); + maxs = M_MAX(maxs,v[2]); + + /* compute key */ + sum = v[0] + v[1] + v[2]; + key = KTA*mins + KTB*maxs + KTC*sum; + key = key % hash->size; + + ht = &hash->item[key]; + + if ( ht->min ) { + if ( ht->min == mins && ht->max == maxs && ht->sum == sum ) + return(ht->iel); + else + while ( ht->nxt && ht->nxt < hash->nhmax ) { + ht = &hash->item[ht->nxt]; + if ( ht->min == mins && ht->max == maxs && ht->sum == sum ) + return(ht->iel); + } + ht->nxt = hash->hnxt; + ht = &hash->item[hash->hnxt]; + ++hash->hnxt; + if ( hash->hnxt == hash->nhmax ) { + fprintf(stdout," ## memory alloc problem (hash)\n"); + return(0); + } + } + + ht->min = mins; + ht->max = maxs; + ht->sum = sum; + ht->iel = iel; + ht->nxt = 0; + + return(iel); +} + + +/* hash triangles : put bdryref and assign a tet per triangle*/ +int MMG_seedTria(pMesh mesh) { + pTetra pt,pt1; + pTria ptt; + Hface htri; + int *adja,v[3],i,k,iel,adj,iadr; + int ncompt = 0; + + /* mem alloc */ + htri.size = mesh->nt; + htri.hnxt = htri.size; + htri.nhmax = (int)(2*htri.size); + htri.item = (hface*)M_calloc(htri.nhmax+1,sizeof(hface),"markTria"); + assert(htri.item); + + for (k=htri.size; k<htri.nhmax; k++) + htri.item[k].nxt = k+1; + + /* store triangles */ + for (k=1; k<=mesh->nt; k++) { + ptt = &mesh->tria[k]; + iel = MMG_hashFace(&htri,k,ptt->v); + if ( !iel ) return(0); + } + + /* init seeds */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + pt1 = &mesh->tetra[adj]; + if ( !adj || ((pt->ref != pt1->ref) ) ) { /*&& (k < adj) IL FAUT TRAITER LES 2 TETS POUR LES SD*/ + v[0] = pt->v[ MMG_idir[i][0] ]; + v[1] = pt->v[ MMG_idir[i][1] ]; + v[2] = pt->v[ MMG_idir[i][2] ]; + iel = MMG_hashFace(&htri,0,v); + if ( !iel ) { /*SD BDRY*/ + if(mesh->info.imprim > 5) printf("on trouve un tr de SD %d : %d %d %d (between %d et %d)\n",++ncompt,v[0],v[1],v[2], + k,adj); + pt->bdryref[i] = 10; + //return(0); + } else { + /*ref bdry or sd bdry*/ + ptt = &mesh->tria[iel]; + pt->bdryref[i] = ptt->ref; + if ( !ptt->splx ) ptt->splx = k; + } + } /*else { + pt->bdryref[i] = pt->ref; + }*/ + } + } + M_free(htri.item); + return(1); +} + + +/* mark boundary vertices */ +int MMG_markBdry(pMesh mesh) { + pTetra pt,pt1; + pTria ptt; + pPoint ppt; + int *adja,adj,iadr,k,i,ii,i1,nt; + + //printf("on arrive avec %d\n",mesh->nt); + nt = 0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + pt1 = &mesh->tetra[adj]; + if ( !adj || ((pt->ref != pt1->ref) && (k < adj)) ) { + for (ii=0; ii<3; ii++) { + i1 = MMG_idir[i][ii]; + ppt = &mesh->point[pt->v[i1]]; + ppt->tag |= M_BDRY; + } + ++nt; + if ( !mesh->nt ) { + if ( (nt < mesh->ntmax-1) ) { + ptt = &mesh->tria[nt]; + ptt->v[0] = pt->v[ MMG_idir[i][0] ]; + ptt->v[1] = pt->v[ MMG_idir[i][1] ]; + ptt->v[2] = pt->v[ MMG_idir[i][2] ]; + if (pt->bdryref[i]!=-1) { + //if(k==13) printf("pour %d (%d) on met %d : %d %d %d\n",k,i,pt->bdryref[i],pt->v[ MMG_idir[i][0] ] + // ,pt->v[ MMG_idir[i][1] ],pt->v[ MMG_idir[i][2] ]); + ptt->ref = pt->bdryref[i]; + } else { + if(mesh->info.imprim < -3 ) + printf("on a un tr qui n''a pas de ref : %d %d %d of %d %d \n",ptt->v[0],ptt->v[1],ptt->v[2],k,adj); + // if(k==10252) { + // printf("ses ref : %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + // printf("face %d : %d %d %d %d\n",i,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + // exit(0); + // } + ptt->ref = (adj)?M_MIN(pt->ref,pt1->ref):10; + pt->bdryref[i] = (adj)?M_MIN(pt->ref,pt1->ref):10; + } + if ( !ptt->splx ) ptt->splx = k; + } + else { + mesh->nt = nt; + } + } + } else if ( (pt->ref != pt1->ref) ) { + if (pt->bdryref[i]==-1) pt->bdryref[i] = (adj)?M_MIN(pt->ref,pt1->ref):10; + } + } + } + + if ( !mesh->nt ) { + mesh->nt = nt; + mesh->ntnil = mesh->nt + 1; + for (k=mesh->ntnil; k<mesh->ntmax-1; k++) + mesh->tria[k].v[2] = k+1; + } + else { + //printf("passe-t-on la ?\n"); + if ( mesh->nt != nt ) + fprintf(stdout," ** WARNING: %d NON-BOUNDARY TRIANGLES : SEVERAL SD CONSIDERED\n", + /*abs*/(mesh->nt-nt),nt,mesh->nt); + + MMG_seedTria(mesh); + /*erase triangles*/ + for (k=1; k<=mesh->nt; k++) + mesh->tria[k].v[0] = 0; + + } +/*printf("on teste\n"); +pTria ptria; +for (k=1; k<=mesh->nt; k++) { + ptria = &mesh->tria[k]; +if(!(mesh->point[ptria->v[0]].tag & M_BDRY)) printf("pbs0 (%d) %d\n",k,ptria->v[0]); +mesh->point[ptria->v[0]].tag |= M_BDRY; +mesh->point[ptria->v[1]].tag |= M_BDRY; +mesh->point[ptria->v[2]].tag |= M_BDRY; +if(!(mesh->point[ptria->v[1]].tag & M_BDRY)) printf("pbs1 (%d) %d\n",k,ptria->v[1]); +if(!(mesh->point[ptria->v[2]].tag & M_BDRY)) printf("pbs2 (%d) %d\n",k,ptria->v[2]); +} */ + return(1); +} + +/* return 0: no point, np: point stored */ +/* edge a-b*/ +int MMG_edgePoint(pHedge hash,int a,int b) { + int key,mins,maxs; + hedge *ha; + + /* compute key */ + mins = a; + maxs = b; + if ( a > b ) { + mins = b; + maxs = a; + } + key = KA*mins + KB*maxs; + key = key % hash->size; + ha = &hash->item[key]; + //printf("cherche %d %d\n",mins,maxs); + if ( !ha->min ) return(0); + else if ( ha->min == mins && ha->max == maxs ) { + return(ha->iel); + } + else if ( ha->nxt ) { + do { + ha = &hash->item[ha->nxt]; + if ( ha->min == mins && ha->max == maxs ) { + return(ha->iel); + } + } + while ( ha->nxt && ha->nxt < hash->nhmax ); + } + return(0); +} + +/*put np on edge a-b*/ +int MMG_edgePut(pHedge hash,int a,int b,int np) { + int key,mins,maxs; + hedge *ha; + + mins = a; + maxs = b; + if ( a > b ) { + mins = b; + maxs = a; + } + key = KA*mins + KB*maxs; + key = key % hash->size; + ha = &hash->item[key]; + + if ( ha->min ) { + /* identical edge */ + if ( ha->min == mins && ha->max == maxs ) { + return(ha->iel); + } + else { + while ( ha->nxt && ha->nxt < hash->nhmax ) { + ha = &hash->item[ha->nxt]; + if ( ha->min == mins && ha->max == maxs ) { + return(ha->iel); + } + } + } + ha->nxt = hash->hnxt; + ha = &hash->item[hash->hnxt]; + ++hash->hnxt; + if ( hash->hnxt >= hash->nhmax ) { + fprintf(stdout," ## Memory alloc problem (edge): %d\n",hash->nhmax); + return(0); + } + } + //printf("insert %d %d\n",mins,maxs); + /* insert */ + ha->min = mins; + ha->max = maxs; + ha->iel = np; + ha->nxt = 0; + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/heap.c b/contrib/mmg3d/build/sources/heap.c new file mode 100644 index 0000000000..9570ce3502 --- /dev/null +++ b/contrib/mmg3d/build/sources/heap.c @@ -0,0 +1,227 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define QUAL 1 +#define VECT 2 + + +/* compare functions */ +static int MMG_compVector(pMesh mesh,pHeap heap,int i,int j) { + pTetra pt,pt1; + pPoint pp1,pp2; + pDispl pd; + int dmin1,dmin2; + short k; + + pd = mesh->disp; + pt = &mesh->tetra[i]; + pt1 = &mesh->tetra[j]; + dmin1 = INT_MAX; + dmin2 = INT_MAX; + + for(k=0; k<4; k++) { + pp1 = &mesh->point[pt->v[k]]; + if ( pp1->tag & M_MOVE && pd->alpha[pt->v[k]] < dmin1 ) + dmin1 = pd->alpha[pt->v[k]]; + pp2 = &mesh->point[pt1->v[k]]; + if ( pp2->tag & M_MOVE && pd->alpha[pt1->v[k]] < dmin2 ) + dmin2 = pd->alpha[pt1->v[k]]; + } + + return( dmin1 > dmin2 ); + /*return( mesh->tetra[i].move < mesh->tetra[j].move );*/ +} + +static int MMG_compQuality(pMesh mesh,pHeap heap,int i,int j) { + return( (mesh->tetra[i].qual > mesh->tetra[j].qual) ); +} + +static int (*MMG_compare)(pMesh ,pHeap ,int ,int ); + + +/* heap management */ +static void MMG_hipup(pMesh mesh,pHeap heap,int k) { + int i,j; + + i = k / 2; + j = heap->cell[k]; + + while ( (i > 0) && MMG_compare(mesh,heap,j,heap->cell[i]) ) { + heap->cell[k] = heap->cell[i]; + heap->link[heap->cell[i]] = k; + k = i; + i /= 2; + } + heap->cell[k] = j; + heap->link[j] = k; +} + + +static void MMG_hipdown(pMesh mesh,pHeap heap,int k) { + int i,j,n; + + i = heap->cell[k]; + n = heap->curc / 2; + + while ( k <= n ) { + j = k+k; + if ( j < heap->curc ) { + if ( MMG_compare(mesh,heap,heap->cell[j+1],heap->cell[j]) ) + j = j+1; + } + if ( MMG_compare(mesh,heap,i,heap->cell[j]) ) + break; + heap->cell[k] = heap->cell[j]; + heap->link[heap->cell[j]] = k; + k = j; + } + + heap->cell[k] = i; + heap->link[i] = k; +} + + +int MMG_hippop(pMesh mesh,pHeap heap) { + int j; + + if ( heap->curc < 1 ) return(0); + j = heap->cell[1]; + if ( heap->curc > 1 ) { + heap->cell[1] = heap->cell[heap->curc]; + heap->link[ heap->cell[heap->curc--] ] = 1; + MMG_hipdown(mesh,heap,1); + } + else + heap->curc--; + + return(j); +} + + +int MMG_hipput(pMesh mesh,pHeap heap,int k) { + if ( heap->curc >= heap->size ) return(0); + + ++heap->curc; + heap->cell[heap->curc] = k; + heap->link[k] = heap->curc; + MMG_hipup(mesh,heap,heap->curc); + + return(1); +} + + +void MMG_hiprep(pMesh mesh,pHeap heap,int k) { + MMG_hipdown(mesh,heap,heap->link[k]); + MMG_hipup(mesh,heap,heap->link[k]); +} + + +void MMG_hipdel(pMesh mesh,pHeap heap,int k) { + if ( heap->link[k] ) + MMG_hipdown(mesh,heap,heap->link[k]); +} + + +Heap *MMG_hipini(pMesh mesh,int nemax,short cmpfunc,double declic,int base) { + pTetra pt; + pPoint ppt; + pDispl pd; + pHeap heap; + int i,k,nm,dmin; + + /* mem alloc */ + heap = (Heap*)M_malloc(sizeof(Heap),"hipini"); + assert(heap); + heap->size = nemax+1; + heap->cell = (int*)M_calloc(heap->size,sizeof(int),"hipini"); + assert(heap->cell); + heap->link = (int*)M_calloc(heap->size,sizeof(int),"hipini"); + assert(heap->link); + heap->curc = 0; + + pd = mesh->disp; + + /* assign function */ + if ( cmpfunc == QUAL ) { + MMG_compare = MMG_compQuality; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] || pt->qual < declic ) continue; + else if ( base > 0 && pt->flag < base ) continue; + else if ( !MMG_hipput(mesh,heap,k) ) return(0); + } + } + else { + MMG_compare = MMG_compVector; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + dmin = INT_MAX; + nm = 0; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt->v[i] ]; + if ( ppt->tag & M_MOVE ) { + if ( pd->alpha[ 3*(pt->v[i]-1) + 1 ] < dmin ) dmin = pd->alpha[ 3*(pt->v[i]-1) + 1 ]; + nm++; + } + } + if ( nm ) { + if ( !MMG_hipput(mesh,heap,k) ) return(0); + } + } + } + + return(heap); +} + + +void MMG_hipfree(pHeap heap) { + M_free(heap->cell); + M_free(heap->link); + M_free(heap); + heap = 0; +} diff --git a/contrib/mmg3d/build/sources/inout.c b/contrib/mmg3d/build/sources/inout.c new file mode 100644 index 0000000000..09e719fab4 --- /dev/null +++ b/contrib/mmg3d/build/sources/inout.c @@ -0,0 +1,1417 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + + +extern short MMG_imprim; +#define sw 4 +#define sd 8 + +int MMG_swapbin(int sbin) +{ + int inv; + char *p_in = (char *) &sbin; + char *p = (char *)&inv; + + + p[0] = p_in[3]; + p[1] = p_in[2]; + p[2] = p_in[1]; + p[3] = p_in[0]; + + return(inv); + /*unsigned char c1, c2, c3, c4; + + c1 = sbin & 255; + c2 = (sbin >> 8) & 255; + c3 = (sbin >> 16) & 255; + c4 = (sbin >> 24) & 255; + + return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4; */ + +} +float MMG_swapf(float sbin) +{ + float out; + char *p_in = (char *) &sbin; + char *p_out = (char *) &out; + p_out[0] = p_in[3]; + p_out[1] = p_in[2]; + p_out[2] = p_in[1]; + p_out[3] = p_in[0]; + + return(out); +} +double MMG_swapd(double sbin) +{ + float out; + char *p_in = (char *) &sbin; + char *p_out = (char *) &out; + int i; + + for(i=0;i<8;i++) + { + p_out[i] = p_in[7-i]; + } + //printf("CONVERTION DOUBLE\n"); + return(out); +} + +/* read mesh data */ +int MMG_loadMesh(pMesh mesh,char *filename) { + FILE* inm; + Hedge hed,hed2; + pPoint ppt; + pTetra pt; + pTria pt1; + int k,dim,ref,bin,bpos,i,tmp; + long posnp,posnt,posne,posnhex,posnpris,posncor,posned,posnq; + char *ptr,data[128],chaine[128]; + int nhex,npris,netmp,ncor,ned,nq; + int p0,p1,p2,p3,p4,p5,p6,p7; + int binch,bdim,iswp,nu1,nu2,nimp,ne; + float fc; + + + posnp = posnt = posne = posnhex = posnpris = 0; + netmp = ncor = ned = 0; + bin = 0; + iswp = 0; + mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0; + npris = nhex = nq = 0; + + strcpy(data,filename); + ptr = strstr(data,".mesh"); + if ( !ptr ) { + strcat(data,".meshb"); + if( !(inm = fopen(data,"rb")) ) { + ptr = strstr(data,".mesh"); + *ptr = '\0'; + strcat(data,".mesh"); + if( !(inm = fopen(data,"r")) ) { + fprintf(stderr," ** %s NOT FOUND.\n",data); + return(0); + } + } else { + bin = 1; + } + } + else { + ptr = strstr(data,".meshb"); + if( !ptr ) { + if( !(inm = fopen(data,"r")) ) { + fprintf(stderr," ** %s NOT FOUND.\n",data); + return(0); + } + } else { + bin = 1; + if( !(inm = fopen(data,"rb")) ) { + fprintf(stderr," ** %s NOT FOUND.\n",data); + return(0); + } + + } + } + + fprintf(stdout," %%%% %s OPENED\n",data); + if (!bin) { + strcpy(chaine,"D"); + while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { + if(!strncmp(chaine,"MeshVersionFormatted",strlen("MeshVersionFormatted"))) { + fscanf(inm,"%d",&mesh->ver); + continue; + } else if(!strncmp(chaine,"Dimension",strlen("Dimension"))) { + fscanf(inm,"%d",&dim); + if(dim!=3) { + fprintf(stdout,"BAD DIMENSION : %d\n",dim); + return(0); + } + continue; + } else if(!strncmp(chaine,"Vertices",strlen("Vertices"))) { + fscanf(inm,"%d",&mesh->np); + posnp = ftell(inm); + continue; + } else if(!strncmp(chaine,"Triangles",strlen("Triangles"))) { + fscanf(inm,"%d",&mesh->nt); + posnt = ftell(inm); + continue; + } else if(!strncmp(chaine,"Tetrahedra",strlen("Tetrahedra"))) { + fscanf(inm,"%d",&mesh->ne); + netmp = mesh->ne; + posne = ftell(inm); + continue; + } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) { + assert(abs(mesh->info.option)==10); + fscanf(inm,"%d",&nhex); + //nhex=0; + posnhex = ftell(inm); + continue; + } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) { + assert(abs(mesh->info.option)==10); + fscanf(inm,"%d",&npris); + //npris=0; + posnpris = ftell(inm); + continue; + } else if(!strncmp(chaine,"Corners",strlen("Corners"))) { + fscanf(inm,"%d",&ncor); + posncor = ftell(inm); + continue; + } else if(!strncmp(chaine,"Edges",strlen("Edges"))) { + fscanf(inm,"%d",&ned); + posned = ftell(inm); + continue; + } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) { + fscanf(inm,"%d",&nq); + posnq = ftell(inm); + continue; + } + } + } else { + bdim = 0; + fread(&mesh->ver,sw,1,inm); + iswp=0; + if(mesh->ver==16777216) + iswp=1; + else if(mesh->ver!=1) { + fprintf(stdout,"BAD FILE ENCODING\n"); + } + fread(&mesh->ver,sw,1,inm); + if(iswp) mesh->ver = MMG_swapbin(mesh->ver); + while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) { + if(iswp) binch=MMG_swapbin(binch); + if(binch==54) break; + if(!bdim && binch==3) { //Dimension + fread(&bdim,sw,1,inm); //NulPos=>20 + if(iswp) bdim=MMG_swapbin(bdim); + fread(&bdim,sw,1,inm); + if(iswp) bdim=MMG_swapbin(bdim); + if(bdim!=3) { + fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); + exit(0); + return(1); + } + continue; + } else if(!mesh->np && binch==4) { //Vertices + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&mesh->np,sw,1,inm); + if(iswp) mesh->np=MMG_swapbin(mesh->np); + posnp = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!mesh->nt && binch==6) {//Triangles + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&mesh->nt,sw,1,inm); + if(iswp) mesh->nt=MMG_swapbin(mesh->nt); + posnt = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!mesh->ne && binch==8) { + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&mesh->ne,sw,1,inm); + if(iswp) mesh->ne=MMG_swapbin(mesh->ne); + netmp = mesh->ne; + posne = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!nhex && binch==10) { + assert(abs(mesh->info.option)==10); + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&nhex,sw,1,inm); + if(iswp) nhex=MMG_swapbin(nhex); + posnhex = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!npris && binch==9) { + assert(abs(mesh->info.option)==10); + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&npris,sw,1,inm); + if(iswp) npris=MMG_swapbin(npris); + posnpris = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!ncor && binch==13) { + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&ncor,sw,1,inm); + if(iswp) ncor=MMG_swapbin(ncor); + posncor = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else if(!ned && binch==5) { //Edges + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + fread(&ned,sw,1,inm); + if(iswp) ned=MMG_swapbin(ned); + posned = ftell(inm); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + continue; + } else { + //printf("on traite ? %d\n",binch); + fread(&bpos,sw,1,inm); //NulPos + if(iswp) bpos=MMG_swapbin(bpos); + //printf("on avance... Nulpos %d\n",bpos); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + } + } + + } + + if ( abs(mesh->info.option)==10 ) { + fprintf(stdout," -- READING %8d HEXA %8d PRISMS\n",nhex,npris); + if(!mesh->ne) netmp = 0; + mesh->ne += 6*nhex + 3*npris; + } + + if ( abs(mesh->info.imprim) > 5 ) + fprintf(stdout," -- READING DATA FILE %s\n",data); + + if ( !mesh->np || !mesh->ne ) { + fprintf(stdout," ** MISSING DATA\n"); + return(0); + } + if ( !MMG_zaldy(mesh) ) return(0); + + /* read mesh vertices */ + mesh->npfixe = mesh->np; + rewind(inm); + fseek(inm,posnp,SEEK_SET); + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if (mesh->ver < 2) { /*float*/ + if (!bin) { + for (i=0 ; i<3 ; i++) { + fscanf(inm,"%f",&fc); + ppt->c[i] = (double) fc; + } + fscanf(inm,"%d",&ppt->ref); + } else { + for (i=0 ; i<3 ; i++) { + fread(&fc,sw,1,inm); + if(iswp) fc=MMG_swapf(fc); + ppt->c[i] = (double) fc; + } + fread(&ppt->ref,sw,1,inm); + if(iswp) ppt->ref=MMG_swapbin(ppt->ref); + } + } else { + if (!bin) + fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref); + else { + for (i=0 ; i<3 ; i++) { + fread(&ppt->c[i],sd,1,inm); + if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]); + } + fread(&ppt->ref,sw,1,inm); + if(iswp) ppt->ref=MMG_swapbin(ppt->ref); + } + } + ppt->tag = M_UNUSED; + } + + /* read mesh triangles */ + mesh->ntfixe = mesh->nt; + rewind(inm); + fseek(inm,posnt,SEEK_SET); + for (k=1; k<=mesh->nt; k++) { + pt1 = &mesh->tria[k]; + if (!bin) + fscanf(inm,"%d %d %d %d",&pt1->v[0],&pt1->v[1],&pt1->v[2],&pt1->ref); + else { + for (i=0 ; i<3 ; i++) { + fread(&pt1->v[i],sw,1,inm); + if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]); + } + fread(&pt1->ref,sw,1,inm); + if(iswp) pt1->ref=MMG_swapbin(pt1->ref); + } + } + /* read mesh quads (option 10)*/ + if(abs(mesh->info.option)==10) { + fprintf(stdout," QUADS READING %d\n",nq); + mesh->ntfixe += 4*nq; + rewind(inm); + fseek(inm,posnq,SEEK_SET); + for (k=1; k<=nq; k++) { + if (!bin) + fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref); + else { + fread(&p0,sw,1,inm); + if(iswp) p0=MMG_swapbin(p0); + fread(&p1,sw,1,inm); + if(iswp) p1=MMG_swapbin(p1); + fread(&p2,sw,1,inm); + if(iswp) p2=MMG_swapbin(p2); + fread(&p3,sw,1,inm); + if(iswp) p3=MMG_swapbin(p3); + fread(&pt1->ref,sw,1,inm); + if(iswp) ref=MMG_swapbin(ref); + } + pt1 = &mesh->tria[++mesh->nt]; + pt1->v[0] = p0; + pt1->v[1] = p1; + pt1->v[2] = p2; + pt1->ref = ref; + pt1 = &mesh->tria[++mesh->nt]; + pt1->v[0] = p0; + pt1->v[1] = p2; + pt1->v[2] = p3; + pt1->ref = ref; + pt1 = &mesh->tria[++mesh->nt]; + pt1->v[0] = p0; + pt1->v[1] = p1; + pt1->v[2] = p3; + pt1->ref = ref; + pt1 = &mesh->tria[++mesh->nt]; + pt1->v[0] = p1; + pt1->v[1] = p2; + pt1->v[2] = p3; + pt1->ref = ref; + + } + } + + /*read and store edges*/ + if (ned) { + if ( !MMG_zaldy4(&hed,ned) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); + ned = 0; + } + mesh->ned = ned; + rewind(inm); + fseek(inm,posned,SEEK_SET); + for (k=1; k<=ned; k++) { + if (!bin) + fscanf(inm,"%d %d %d",&nu1,&nu2,&ref); + else { + fread(&nu1,sw,1,inm); + if(iswp) nu1=MMG_swapbin(nu1); + fread(&nu2,sw,1,inm); + if(iswp) nu2=MMG_swapbin(nu2); + fread(&ref,sw,1,inm); + if(iswp) ref=MMG_swapbin(ref); + } + if(MMG_edgePut(&hed,nu1,nu2,2)>1) { + fprintf(stdout," ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2); + } + } + } + + /* read mesh tetrahedra */ + mesh->nefixe = mesh->ne; + rewind(inm); + fseek(inm,posne,SEEK_SET); + for (k=1; k<=netmp; k++) { + pt = &mesh->tetra[k]; + if (!bin) + fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref); + else { + + for (i=0 ; i<4 ; i++) { + fread(&pt->v[i],sw,1,inm); + if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]); + } + fread(&ref,sw,1,inm); + if(iswp) ref=MMG_swapbin(ref); + } + pt->ref = ref;//0;//ref ; + for(i=0 ; i<4 ; i++) + pt->bdryref[i] = -1; + + if (ned) { + for(i=0 ; i<6 ; i++) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2); + } + + } else { + for(i=0 ; i<6 ; i++) + pt->bdryinfo[i] = 0; + } + } + if (ned) M_free(hed.item); + + /*read corners*/ + if (ncor) { + rewind(inm); + fseek(inm,posncor,SEEK_SET); + mesh->ncor = ncor; + for (k=1; k<=ncor; k++) { + if (!bin) + fscanf(inm,"%d",&ref); + else { + fread(&ref,sw,1,inm); + if(iswp) ref=MMG_swapbin(ref); + } + ppt = &mesh->point[ref]; + ppt->geom = M_CORNER; + } + } + + + if ( abs(mesh->info.option)==10 ) { + if(bin) { + printf("NOT SUPPORTED\n"); + exit(0); + } + if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); + npris = 0; + nhex = 0; + } + + /*read hexa and transform to tetra*/ + rewind(inm); + fseek(inm,posnhex,SEEK_SET); + for (k=1; k<=nhex; k++) { + fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&p6,&p7,&ref); + //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); + //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7); + MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,p0,p1,p2,p3,p4,p5,p6,p7,ref); + } + + /*read prism and transform to tetra + ---> compatibility pbs ==> hash edge and switch case*/ + rewind(inm); + fseek(inm,posnpris,SEEK_SET); + nimp = 0; + ne = netmp+6*nhex; + for (k=1; k<=npris; k++) { + fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); + if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref)) + { + if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); + mesh->ne += 5; + ne += 8; + nimp++; + continue; + } + ne += 3; + } + if(abs(mesh->info.imprim) > 3 )fprintf(stdout," %d INVALID DECOMPOSITION\n\n",nimp); + } + + if ( abs(mesh->info.imprim) > 3 ) { + fprintf(stdout," NUMBER OF GIVEN VERTICES %8d\n",mesh->npfixe); + if ( mesh->ntfixe ) + fprintf(stdout," NUMBER OF GIVEN TRIANGLES %8d\n",mesh->ntfixe); + fprintf(stdout," NUMBER OF GIVEN TETRAHEDRA %8d\n",mesh->nefixe); + if ( ncor ) + fprintf(stdout," NUMBER OF GIVEN CORNERS %8d\n",ncor); + if ( ned ) + fprintf(stdout," NUMBER OF GIVEN EDGES %8d\n",ned); + } + fclose(inm); + return(1); +} + + +/* load solution (metric) */ +int MMG_loadSol(pSol sol,char *filename,int npmax) { + FILE *inm; + float fsol; + double tmp; + int binch,bdim,iswp; + int k,i,isol,type,bin,dim,btyp,bpos; + long posnp; + char *ptr,data[128],chaine[128]; + + posnp = 0; + bin = 0; + iswp = 0; + + strcpy(data,filename); + ptr = strstr(data,".mesh"); + if ( ptr ) *ptr = '\0'; + strcat(data,".solb"); + if( !(inm = fopen(data,"rb")) ) { + ptr = strstr(data,".solb"); + *ptr = '\0'; + strcat(data,".sol"); + if( !(inm = fopen(data,"r")) ) { + fprintf(stderr," ** %s NOT FOUND.\n",data); + return(1); + } + } else { + bin = 1; + } + fprintf(stdout," %%%% %s OPENED\n",data); + + + if(!bin) { + strcpy(chaine,"DDD"); + while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { + if(!strncmp(chaine,"Dimension",strlen("Dimension"))) { + fscanf(inm,"%d",&dim); + if(dim!=3) { + fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); + return(1); + } + continue; + } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) { + fscanf(inm,"%d",&sol->np); + fscanf(inm,"%d",&type); + if(type!=1) { + fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type); + return(1); + } + fscanf(inm,"%d",&btyp); + posnp = ftell(inm); + break; + } + } + } else { + fread(&binch,sw,1,inm); + iswp=0; + if(binch==16777216) iswp=1; + else if(binch!=1) { + fprintf(stdout,"BAD FILE ENCODING\n"); + } + fread(&sol->ver,sw,1,inm); + if(iswp) sol->ver = MMG_swapbin(sol->ver); + while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) { + if(iswp) binch=MMG_swapbin(binch); + if(binch==54) break; + if(binch==3) { //Dimension + fread(&bdim,sw,1,inm); //NulPos=>20 + if(iswp) bdim=MMG_swapbin(bdim); + fread(&bdim,sw,1,inm); + if(iswp) bdim=MMG_swapbin(bdim); + if(bdim!=3) { + fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); + exit(0); + return(1); + } + continue; + } else if(binch==62) { //SolAtVertices + fread(&binch,sw,1,inm); //NulPos + if(iswp) binch=MMG_swapbin(binch); + fread(&sol->np,sw,1,inm); + if(iswp) sol->np=MMG_swapbin(sol->np); + fread(&binch,sw,1,inm); //nb sol + if(iswp) binch=MMG_swapbin(binch); + if(binch!=1) { + fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type); + return(1); + } + fread(&btyp,sw,1,inm); //typsol + if(iswp) btyp=MMG_swapbin(btyp); + posnp = ftell(inm); + break; + } else { + fread(&bpos,sw,1,inm); //Pos + if(iswp) bpos=MMG_swapbin(bpos); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + } + } + + } + if ( !sol->np ) { + fprintf(stdout," ** MISSING DATA\n"); + return(1); + } + + if ( btyp!= 1 && btyp!=3 ) { + fprintf(stdout," ** DATA IGNORED\n"); + sol->np = 0; + return(1); + } + + sol->offset = (btyp==1) ? 1 : 6; + + if ( abs(MMG_imprim) > 5 ) + fprintf(stdout," -- READING DATA FILE %s\n",data); + + if ( !sol->np ) { + fprintf(stdout," ** MISSING DATA\n"); + return(0); + } + sol->npfixe = sol->np; + sol->npmax = npmax; + if ( !MMG_zaldy3(sol) ) return(0); + + /* read mesh solutions */ + sol->npfixe = sol->np; + rewind(inm); + fseek(inm,posnp,SEEK_SET); + for (k=1; k<=sol->np; k++) { + isol = (k-1) * sol->offset + 1; + if (sol->ver == 1) { + for (i=0; i<sol->offset; i++) { + if(!bin){ + fscanf(inm,"%f",&fsol); + sol->met[isol + i] = (double) fsol; + } else { + fread(&fsol,sw,1,inm); + if(iswp) fsol=MMG_swapf(fsol); + sol->met[isol + i] = (double) fsol; + } + } + } else { + for (i=0; i<sol->offset; i++) { + if(!bin){ + fscanf(inm,"%lf",&sol->met[isol + i]); + + } else { + fread(&sol->met[isol + i],sd,1,inm); + if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]); + } + } + } + /* MMG_swap data */ + if ( sol->offset == 6 ) { + tmp = sol->met[isol + 2]; + sol->met[isol + 2] = sol->met[isol + 3]; + sol->met[isol + 3] = tmp; + } + } + + if ( abs(MMG_imprim) > 3 ) + fprintf(stdout," NUMBER OF GIVEN DATA %8d\n",sol->npfixe); + + fclose(inm); + return(1); +} + + +int MMG_loadVect(pMesh mesh,char *filename,int npmax) { + FILE *inm; + pDispl pd; + float fsol; + int binch,bdim,iswp; + int k,i,type,bin,dim,btyp,bpos,iadr; + long posnp; + char *ptr,data[128],chaine[128]; + + pd = mesh->disp; + + posnp = 0; + bin = 0; + iswp = 0; + + strcpy(data,filename); + ptr = strstr(data,".mesh"); + if ( ptr ) *ptr = '\0'; + strcat(data,".solb"); + if( !(inm = fopen(data,"rb")) ) { + ptr = strstr(data,".solb"); + *ptr = '\0'; + strcat(data,".sol"); + if( !(inm = fopen(data,"r")) ) { + fprintf(stderr," ** %s NOT FOUND.\n",data); + return(1); + } + } else { + bin = 1; + } + fprintf(stdout," %%%% %s OPENED\n",data); + + + if(!bin) { + strcpy(chaine,"DDD"); + while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { + if(!strncmp(chaine,"Dimension",strlen("Dimension"))) { + fscanf(inm,"%d",&dim); + if(dim!=3) { + fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); + return(1); + } + continue; + } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) { + fscanf(inm,"%d",&pd->np); + fscanf(inm,"%d",&type); + if(type!=1) { + fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type); + return(1); + } + fscanf(inm,"%d",&btyp); + posnp = ftell(inm); + break; + } + } + } else { + fread(&pd->ver,sw,1,inm); + iswp=0; + if(pd->ver==16777216) iswp=1; + else if(pd->ver!=1) { + fprintf(stdout,"BAD FILE ENCODING\n"); + } + fread(&pd->ver,sw,1,inm); + if(iswp) pd->ver = MMG_swapbin(pd->ver); + while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) { + if(iswp) binch=MMG_swapbin(binch); + if(binch==54) break; + if(binch==3) { //Dimension + fread(&bdim,sw,1,inm); //Pos=>20 + if(iswp) bdim=MMG_swapbin(bdim); + fread(&bdim,sw,1,inm); + if(iswp) bdim=MMG_swapbin(bdim); + if(bdim!=3) { + fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); + exit(0); + return(1); + } + continue; + } else if(binch==62) { //SolAtVertices + fread(&binch,sw,1,inm); //Pos + if(iswp) binch=MMG_swapbin(binch); + fread(&pd->np,sw,1,inm); + if(iswp) pd->np=MMG_swapbin(pd->np); + fread(&binch,sw,1,inm); //nb sol + if(iswp) binch=MMG_swapbin(binch); + if(binch!=1) { + fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type); + return(1); + } + fread(&btyp,sw,1,inm); //typsol + if(iswp) btyp=MMG_swapbin(btyp); + posnp = ftell(inm); + break; + } else { + fread(&bpos,sw,1,inm); //Pos + if(iswp) bpos=MMG_swapbin(bpos); + rewind(inm); + fseek(inm,bpos,SEEK_SET); + } + } + + } + if ( !pd->np ) { + fprintf(stdout," ** MISSING DATA\n"); + return(0); + } + else if ( pd->np != mesh->np ) { + fprintf(stdout," ** WRONG DATA\n"); + return(0); + } + + if ( btyp != 2 ) { + fprintf(stdout," ** DATA IGNORED\n"); + return(0); + } + + if ( abs(mesh->info.imprim) > 5 ) + fprintf(stdout," -- READING DATA FILE %s\n",data); + + /* read mesh solutions */ + rewind(inm); + fseek(inm,posnp,SEEK_SET); + for (k=1; k<=pd->np; k++) { + iadr = (k - 1) * 3 + 1; + if (pd->ver < 2) { + for (i=0; i<3; i++) { + if(!bin){ + fscanf(inm,"%f",&fsol); + pd->mv[iadr + i] = (double) fsol; + } else { + fread(&fsol,sw,1,inm); + if(iswp) fsol=MMG_swapf(fsol); + pd->mv[iadr + i] = (double) fsol; + } + } + } else { + for (i=0; i<3; i++) { + if(!bin){ + fscanf(inm,"%lf",&pd->mv[iadr + i]); + } else { + fread(&pd->mv[iadr + i],sd,1,inm); + if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]); + } + } + } + } + + if ( abs(mesh->info.imprim) > 3 ) + fprintf(stdout," NUMBER OF GIVEN DATA %8d\n",pd->np); + + fclose(inm); + return(1); +} + + +/* save mesh to disk */ +int MMG_saveMesh(pMesh mesh,char *filename) { + FILE* inm; + Hedge hed; + pPoint ppt; + pTria pt1; + pTetra pt; + int i,k,np,ne,nc,ned,*cor,*ed,ref,bin,bpos; + char *ptr,data[128],chaine[128]; + int binch,nu1,nu2; + mesh->ver = 2; //double precision + bin = 0; + strcpy(data,filename); + ptr = strstr(data,".mesh"); + if ( !ptr ) { + strcat(data,".meshb"); + if( !(inm = fopen(data,"wb")) ) { + ptr = strstr(data,".mesh"); + *ptr = '\0'; + strcat(data,".mesh"); + if( !(inm = fopen(data,"w")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } + } else { + bin = 1; + } + } + else { + ptr = strstr(data,".meshb"); + if( ptr ) bin = 1; + if( !(inm = fopen(data,"w")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } + } + fprintf(stdout," %%%% %s OPENED\n",data); + + /*entete fichier*/ + if(!bin) { + strcpy(&chaine[0],"MeshVersionFormatted 2\n"); + fprintf(inm,"%s",chaine); + strcpy(&chaine[0],"\n\nDimension 3\n"); + fprintf(inm,"%s ",chaine); + } else { + binch = 1; //MeshVersionFormatted + fwrite(&binch,sw,1,inm); + binch = 2; //version + fwrite(&binch,sw,1,inm); + binch = 3; //Dimension + fwrite(&binch,sw,1,inm); + bpos = 20; //Pos + fwrite(&bpos,sw,1,inm); + binch = 3; + fwrite(&binch,sw,1,inm); + + } + + /* compact vertices */ + if(mesh->ncor) { + cor = (int*) M_calloc(mesh->ncor,sizeof(int),"MMG_savemesh"); + assert(cor); + } + if(mesh->ned) { + if ( !MMG_zaldy4(&hed,mesh->ned) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n"); + mesh->ned = 0; + } + ed = (int*)M_calloc(2*mesh->ned,sizeof(int),"MMG_savemesh"); + assert(ed); + } + np = 0; + nc = 0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ppt->tmp = ++np; + if ( ppt->geom & M_CORNER ) cor[nc++] = ppt->tmp; + } + assert(mesh->ncor==nc); + if(!bin) { + strcpy(&chaine[0],"\n\nVertices\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",np); + } else { + binch = 4; //Vertices + fwrite(&binch,sw,1,inm); + bpos += 12+(1+3*mesh->ver)*4*np; //NullPos + fwrite(&bpos,sw,1,inm); + fwrite(&np,sw,1,inm); + } + for(k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + //if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k); + if(!bin) { + fprintf(inm,"%.15lg %.15lg %.15lg %d\n",ppt->c[0],ppt->c[1],ppt->c[2],ppt->ref); + } else { + fwrite((unsigned char*)&ppt->c[0],sd,1,inm); + fwrite((unsigned char*)&ppt->c[1],sd,1,inm); + fwrite((unsigned char*)&ppt->c[2],sd,1,inm); + fwrite((unsigned char*)&ppt->ref,sw,1,inm); + } + } + + /* rebuild triangles tabular and write triangles */ + mesh->nt = 0; + if(MMG_markBdry(mesh)) { + if(!bin) { + strcpy(&chaine[0],"\n\nTriangles\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d \n",mesh->nt); + } else { + binch = 6; //Triangles + fwrite(&binch,sw,1,inm); + bpos += 12+16*mesh->nt; //Pos + fwrite(&bpos,sw,1,inm); + fwrite(&mesh->nt,sw,1,inm); + } + for (k=1; k<=mesh->nt; k++) { + pt1 = &mesh->tria[k]; + ref = pt1->ref; + if(!bin) { + fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp + ,mesh->point[pt1->v[2]].tmp,ref); + } else { + fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm); + fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm); + fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm); + fwrite(&ref,sw,1,inm); + } + } + } + + /* write tetrahedra */ + ne = 0; + ned = 0; + //printf("avt %d\n",mesh->ned); + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + if(mesh->ned) { + for (i=0 ; i<6 ; i++) { + if (pt->bdryinfo[i]) { + nu1 = pt->v[MMG_iare[i][0]]; + nu2 = pt->v[MMG_iare[i][1]]; + if (MMG_edgePut(&hed,nu1,nu2,2)<=1) { + ed[2*ned] = (mesh->point[nu1]).tmp; + ed[2*ned + 1] = (mesh->point[nu2]).tmp; + ned++; + } + } + } + } + ne++; + } + //printf("ned %d\n",ned); + if(!bin) { + strcpy(&chaine[0],"\n\nTetrahedra\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",ne); + } else { + binch = 8; //Tetra + fwrite(&binch,sw,1,inm); + bpos += 12 + 20*ne;//Pos + fwrite(&bpos,sw,1,inm); + fwrite((unsigned char*)&ne,sw,1,inm); + } + ne=0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + ne++; + ref = pt->ref; + if(!bin) { + fprintf(inm,"%d %d %d %d %d\n",mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp + ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref); + } else { + fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm); + fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm); + fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm); + fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm); + fwrite(&ref,sw,1,inm); + } + } + + if(mesh->ned) { + if(!bin) { + strcpy(&chaine[0],"\n\nEdges\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",ned); + } else { + binch = 5; //Edges + fwrite(&binch,sw,1,inm); + bpos += 12 + 3*4*ned;//Pos + fwrite(&bpos,sw,1,inm); + fwrite((unsigned char*)&ned,sw,1,inm); + } + for (k=0; k<ned; k++) { + ref = 0; + if(!bin) { + fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref); + } else { + fwrite(&ed[2*k],sw,1,inm); + fwrite(&ed[2*k+1],sw,1,inm); + fwrite(&ref,sw,1,inm); + } + } + M_free(hed.item); + } + + /* write corners */ + if(!bin) { + strcpy(&chaine[0],"\n\nCorners\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",mesh->ncor); + } else { + binch = 13; //Corners + fwrite(&binch,sw,1,inm); + bpos += 12 + 4*mesh->ncor;//Pos + fwrite(&bpos,sw,1,inm); + fwrite((unsigned char*)&mesh->ncor,sw,1,inm); + } + for (k=0; k<mesh->ncor; k++) { + if(!bin) { + fprintf(inm,"%d \n",cor[k]); + } else { + fwrite(&cor[k],sw,1,inm); + } + } + /*fin fichier*/ + if(!bin) { + strcpy(&chaine[0],"\n\nEnd\n"); + fprintf(inm,"%s",chaine); + } else { + binch = 54; //End + fwrite(&binch,sw,1,inm); + } + fclose(inm); + if(mesh->ncor) M_free(cor); + if ( mesh->info.imprim ) { + fprintf(stdout," NUMBER OF GIVEN VERTICES %8d\n",mesh->npfixe); + if ( mesh->ntfixe ) + fprintf(stdout," NUMBER OF GIVEN TRIANGLES %8d\n",mesh->ntfixe); + fprintf(stdout," NUMBER OF GIVEN ELEMENTS %8d\n",mesh->nefixe); + fprintf(stdout," TOTAL NUMBER OF VERTICES %8d\n",np); + fprintf(stdout," TOTAL NUMBER OF TRIANGLES %8d\n",mesh->nt); + fprintf(stdout," TOTAL NUMBER OF ELEMENTS %8d\n",ne); + if ( mesh->ncor ) + fprintf(stdout," TOTAL NUMBER OF CORNERS %8d\n",mesh->ncor); + if ( mesh->ned ) + fprintf(stdout," TOTAL NUMBER OF EDGES %8d\n",ned); + } + //if(ned!=mesh->ned) exit(0); + return(1); + +} + + +int MMG_saveSol(pMesh mesh,pSol sol,char *filename) { + FILE* inm; + pPoint ppt; + float fsol; + double tmp; + int i,k,nbl,isol,bin,bpos,typ; + char *ptr,data[128],chaine[128]; + int binch; + + if ( !sol->np ) return(1); + bin = 1; + strcpy(data,filename); + ptr = strstr(data,".meshb"); + if ( ptr ) *ptr = '\0'; + else { + ptr = strstr(data,".mesh"); + if ( ptr ) { + *ptr = '\0'; + bin = 0; + } else { + ptr = strstr(data,".solb"); + if ( ptr ) { + *ptr = '\0'; + bin = 1; + } else { + ptr = strstr(data,".sol"); + if ( ptr ) { + *ptr = '\0'; + bin = 0; + } + } + } + } + if ( bin ) + strcat(data,".solb"); + else + strcat(data,".sol"); + + sol->ver = 2; + if( bin && !(inm = fopen(data,"wb")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } else { + if( !(inm = fopen(data,"w")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } + } + fprintf(stdout," %%%% %s OPENED\n",data); + + /*entete fichier*/ + if(!bin) { + strcpy(&chaine[0],"MeshVersionFormatted 2\n"); + fprintf(inm,"%s",chaine); + strcpy(&chaine[0],"\n\nDimension 3\n"); + fprintf(inm,"%s ",chaine); + } else { + binch = 1; //MeshVersionFormatted + fwrite(&binch,sw,1,inm); + binch = 2; //version + fwrite(&binch,sw,1,inm); + binch = 3; //Dimension + fwrite(&binch,sw,1,inm); + bpos = 20; //Pos + fwrite(&bpos,sw,1,inm); + binch = 3; + fwrite(&binch,sw,1,inm); + + } + + + switch(sol->offset) { + case 1: + typ = 1; + break; + case 6: + typ = 3; + break; + default: + fprintf(stdout," ** DATA IGNORED\n"); + return(0); + } + + /* write data */ + nbl = 0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + nbl++; + } + + if(!bin) { + strcpy(&chaine[0],"\n\nSolAtVertices\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",nbl); + fprintf(inm,"%d %d\n",1,typ); + } else { + binch = 62; //Vertices + fwrite(&binch,sw,1,inm); + bpos += 20+(sol->offset*sol->ver)*4*nbl; //Pos + fwrite(&bpos,sw,1,inm); + fwrite(&nbl,sw,1,inm); + binch = 1; //nb sol + fwrite(&binch,sw,1,inm); + binch = typ; //typ sol + fwrite(&binch,sw,1,inm); + } + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + isol = (k-1) * sol->offset + 1; + /* swap data */ + if ( sol->offset == 6 ) { + tmp = sol->met[isol + 2]; + sol->met[isol + 2] = sol->met[isol + 3]; + sol->met[isol + 3] = tmp; + } + if (sol->ver < 2) { + if(!bin) { + for (i=0; i<sol->offset; i++) { + fsol = (float) sol->met[isol + i]; + fprintf(inm,"%f ",fsol); + } + fprintf(inm,"\n"); + } else { + for (i=0; i<sol->offset; i++) { + fsol = (float) sol->met[isol + i]; + fwrite(&fsol,sw,1,inm); + } + } + } else { + if(!bin) { + for (i=0; i<sol->offset; i++) + fprintf(inm,"%.15lg ",sol->met[isol + i]); + fprintf(inm,"\n"); + } else { + for (i=0; i<sol->offset; i++) + fwrite(&sol->met[isol + i],sd,1,inm); + } + + } + } + + /*fin fichier*/ + if(!bin) { + strcpy(&chaine[0],"\n\nEnd\n"); + fprintf(inm,"%s",chaine); + } else { + binch = 54; //End + fwrite(&binch,sw,1,inm); + } + fclose(inm); + return(1); +} + +/*save the node speed : coornew-coorold/dt*/ +int MMG_saveVect(pMesh mesh,char *filename) { + FILE* inm; + pDispl pd; + pPoint ppt; + double dsol,dd; + int i,k,nbl,bin,bpos,typ; + char *ptr,data[128],chaine[128]; + unsigned char binch; + + pd = mesh->disp; + pd->ver = 2; + + bin = 0; + strcpy(data,filename); + ptr = strstr(data,".meshb"); + if ( ptr ) *ptr = '\0'; + else { + ptr = strstr(data,".mesh"); + if ( ptr ) { + *ptr = '\0'; + bin = 0; + } + } + if ( bin ) + strcat(data,".o.solb"); + else + strcat(data,".o.sol"); + if( bin && !(inm = fopen(data,"wb")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } else { + if( !(inm = fopen(data,"w")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } + } + fprintf(stdout," %%%% %s OPENED\n",data); + + /*entete fichier*/ + if(!bin) { + strcpy(&chaine[0],"MeshVersionFormatted 2\n"); + fprintf(inm,"%s",chaine); + strcpy(&chaine[0],"\n\nDimension 3\n"); + fprintf(inm,"%s ",chaine); + } else { + binch = 1; //MeshVersionFormatted + fwrite(&binch,sw,1,inm); + binch = pd->ver; //version + fwrite(&binch,sw,1,inm); + binch = 3; //Dimension + fwrite(&binch,sw,1,inm); + bpos = 20; //Pos + fwrite(&bpos,sw,1,inm); + binch = 3; + fwrite(&binch,sw,1,inm); + + } + typ = 2; + + /* write data */ + nbl = 0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + nbl++; + } + + if(!bin) { + strcpy(&chaine[0],"\n\nSolAtVertices\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",nbl); + fprintf(inm,"%d %d\n",1,typ); + } else { + binch = 62; //SolAtVertices + fwrite(&binch,sw,1,inm); + bpos += 20+(3*pd->ver)*4*nbl; //Pos + fwrite(&bpos,sw,1,inm); + fwrite(&nbl,sw,1,inm); + binch = 1; //nb sol + fwrite(&binch,sw,1,inm); + binch = typ; //typ sol + fwrite(&binch,sw,1,inm); + } + + + dd = mesh->info.delta / (double)PRECI; + fprintf(stdout," DT %e\n",mesh->info.dt); + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + for (i=0 ; i<3 ; i++) { + dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt; + if(!bin) { + fprintf(inm,"%.15lg ",dsol); + } else { + fwrite(&dsol,sd,1,inm); + } + } + if (!bin) fprintf(inm,"\n"); + } + + + /*fin fichier*/ + if(!bin) { + strcpy(&chaine[0],"\n\nEnd\n"); + fprintf(inm,"%s",chaine); + } else { + binch = 54; //End + fwrite(&binch,sw,1,inm); + } + fclose(inm); + + return(1); +} diff --git a/contrib/mmg3d/build/sources/length.c b/contrib/mmg3d/build/sources/length.c new file mode 100644 index 0000000000..89304ea9ae --- /dev/null +++ b/contrib/mmg3d/build/sources/length.c @@ -0,0 +1,235 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* compute aniso edge MMG_length */ +double MMG_long_ani(double *ca,double *cb,double *sa,double *sb) { + double ux,uy,uz,dd1,dd2,len; + + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + + dd1 = sa[0]*ux*ux + sa[3]*uy*uy + sa[5]*uz*uz \ + + 2.0*(sa[1]*ux*uy + sa[2]*ux*uz + sa[4]*uy*uz); + if ( dd1 <= 0.0 ) dd1 = 0.0; + + dd2 = sb[0]*ux*ux + sb[3]*uy*uy + sb[5]*uz*uz \ + + 2.0*(sb[1]*ux*uy + sb[2]*ux*uz + sb[4]*uy*uz); + if ( dd2 <= 0.0 ) dd2 = 0.0; + + /*longueur approchee*/ + /*precision a 3.5 10e-3 pres*/ + if(fabs(dd1-dd2) < 0.05 ) { + //printf("bonne precision %e \n",sqrt(0.5*(dd1+dd2)) - (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0 ); + len = sqrt(0.5*(dd1+dd2)); + return(len); + } + len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0; + + return(len); +} + +double MMG_long_ani_init(double *ca,double *cb,double *sa,double *sb) { + double ux,uy,uz,dd1,dd2,len; + + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + + dd1 = sa[0]*ux*ux + sa[3]*uy*uy + sa[5]*uz*uz \ + + 2.0*(sa[1]*ux*uy + sa[2]*ux*uz + sa[4]*uy*uz); + if ( dd1 <= 0.0 ) dd1 = 0.0; + + dd2 = sb[0]*ux*ux + sb[3]*uy*uy + sb[5]*uz*uz \ + + 2.0*(sb[1]*ux*uy + sb[2]*ux*uz + sb[4]*uy*uz); + if ( dd2 <= 0.0 ) dd2 = 0.0; + + len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0; + + return(len); +} + +/* compute iso edge MMG_length */ +double MMG_long_iso(double *ca,double *cb,double *ma,double *mb) { + double ux,uy,uz,dd,rap,len; + double sa,sb; + + sa = *ma; + sb = *mb; + + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + dd = sqrt(ux*ux + uy*uy + uz*uz); + + rap = (sb - sa) / sa; + if ( fabs(rap) < EPS1 ) + /*len = dd * (2.0-EPS1) / (2.0*sa);*/ + len = dd / sa; + else + /*len = max(dd/sa,dd/sb);*/ + len = dd * (1.0/sa + 1.0/sb + 8.0 / (sa+sb)) / 6.0; + + + return(len); +} + + +/* print histo of edge lengths */ +int MMG_prilen(pMesh mesh,pSol sol) { + pTetra pt; + double lavg,len,ecart,som,lmin,lmax,*ca,*cb,*ma,*mb; + int k,l,lon,navg,ia,ipa,ipb,iamin,ibmin,iamax,ibmax,dep,hl[10]; + int iadr; + List list; + static double bd[9] = {0.0, 0.2, 0.5, 0.7071, 0.9, 1.111, 1.4142, 2.0, 5.0 }; + navg = 0; + lavg = 0.0; + lmin = 1.e20; + lmax = 0.0; + som = 0.0; + dep = 1; + iamin = 0; + ibmin = 0; + iamax = 0; + ibmax = 0; + + for (k=1; k<10; k++) hl[k] = 0; + + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + + for (ia=0; ia<6; ia++) { + lon = MMG_coquil(mesh,k,ia,&list); + if ( lon < 2 ) continue; + for (l=2; l<=lon; l++) + if ( list.tetra[l] < 6*k ) break; + + if ( l <= lon ) continue; + + ipa = MMG_iare[ia][0]; + ipb = MMG_iare[ia][1]; + ca = &mesh->point[pt->v[ipa]].c[0]; + cb = &mesh->point[pt->v[ipb]].c[0]; + + iadr = (pt->v[ipa]-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (pt->v[ipb]-1)*sol->offset + 1; + mb = &sol->met[iadr]; + if(sol->offset==6) + len = MMG_long_ani_init(ca,cb,ma,mb); + else + len = MMG_length(ca,cb,ma,mb); + navg++; + ecart = len; + lavg += len; + /* update efficiency index */ + if ( ecart > 1.0 ) ecart = 1.0 / ecart; + + som += (ecart - 1.0); + + /* find largest, smallest edge */ + if (len < lmin) { + lmin = len; + iamin = pt->v[ipa]; + ibmin = pt->v[ipb]; + } + else if (len > lmax) { + lmax = len; + iamax = pt->v[ipa]; + ibmax = pt->v[ipb]; + } + + /* update histogram */ + if (len < bd[3]) { + if (len > bd[2]) hl[3]++; + else if (len > bd[1]) hl[2]++; + else hl[1]++; + } + else if (len < bd[5]) { + if (len > bd[4]) hl[5]++; + else if (len > bd[3]) hl[4]++; + } + else if (len < bd[6]) hl[6]++; + else if (len < bd[7]) hl[7]++; + else if (len < bd[8]) hl[8]++; + else hl[9]++; + } + /* /if ( dep < 0 ) break;*/ + } + + fprintf(stdout,"\n -- RESULTING EDGE LENGTHS %d\n",navg); + fprintf(stdout," AVERAGE LENGTH %12.4f\n",lavg / (double)navg); + fprintf(stdout," SMALLEST EDGE LENGTH %12.4f %6d %6d\n", + lmin,iamin,ibmin); + fprintf(stdout," LARGEST EDGE LENGTH %12.4f %6d %6d \n", + lmax,iamax,ibmax); + fprintf(stdout," EFFICIENCY INDEX %12.4f\n",exp(som/(double)navg)); + if ( hl[4]+hl[5]+hl[6] ) + fprintf(stdout," %6.2f < L <%5.2f %8d %5.2f %% \n", + bd[3],bd[6],hl[4]+hl[5]+hl[6],100.*(hl[4]+hl[5]+hl[6])/(double)navg); + + if ( abs(mesh->info.imprim) > 4 ) { + fprintf(stdout,"\n HISTOGRAMM\n"); + if ( hl[1] ) + fprintf(stdout," 0.00 < L < 0.20 %8d %5.2f %% \n", + hl[1],100.*(hl[1]/(float)navg)); + if ( lmax > 0.2 ) { + for (k=2; k<9; k++) { + if ( hl[k] > 0 ) + fprintf(stdout," %6.2f < L <%5.2f %8d %5.2f %% \n", + bd[k-1],bd[k],hl[k],100.*(hl[k]/(float)navg)); + } + if ( hl[9] ) + fprintf(stdout," 5. < L %8d %5.2f %% \n", + hl[9],100.*(hl[9]/(float)navg)); + } + } + + return(1); +} diff --git a/contrib/mmg3d/build/sources/libmmg3d.h b/contrib/mmg3d/build/sources/libmmg3d.h new file mode 100644 index 0000000000..22c002499c --- /dev/null +++ b/contrib/mmg3d/build/sources/libmmg3d.h @@ -0,0 +1,128 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +typedef struct { + double c[3]; + int mark,tmp; + int ref; + unsigned char flag,tag,tmp2; + unsigned char geom; +} MMG_Point; +typedef MMG_Point * MMG_pPoint; + +typedef struct { + int v[4]; + int mark; + double qual; + int ref,bdryref[4]; + unsigned char flag,edge,tabedg; + unsigned char bdryinfo[6]; +} MMG_Tetra; +typedef MMG_Tetra * MMG_pTetra; + +typedef struct { + int v[3],splx; + int ref; +} MMG_Tria; +typedef MMG_Tria * MMG_pTria; + +typedef struct { + int np,ver; + double *mv,*cold; + short *alpha; +} MMG_Displ; +typedef MMG_Displ * MMG_pDispl; + +typedef struct { + unsigned char ddebug; + unsigned char noswap,noinsert,nomove,bdry; + short imprim,option,memory,rn,rn2; + int bucksiz; + double delta,dt; + double min[3],max[3]; + +} MMG_Info; + +typedef struct { + int np,ne,nt,ncor,ned,npmax,nemax,ntmax; + int npfixe,nefixe,ntfixe,mark; + int npnil,nenil,ntnil; + int *adja,ver; + char *name,*outf,*move; + unsigned char flag,booleen; + + MMG_pPoint point; + MMG_pTetra tetra; + MMG_pTria tria; + MMG_pDispl disp; + MMG_Info info; +} MMG_Mesh; +typedef MMG_Mesh * MMG_pMesh; + +typedef struct { + int np,npfixe,npmax,ver; + double *met,hmin,hmax; + char *name; + double *metold; + unsigned char offset; +} MMG_Sol; +typedef MMG_Sol * MMG_pSol; + +/* inout */ +int MMG_loadMesh(MMG_pMesh ,char *); +int MMG_loadSol(MMG_pSol ,char *,int ); +int MMG_loadVect(MMG_pMesh ,char *,int ); +int MMG_saveMesh(MMG_pMesh ,char *); +int MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *); +int MMG_saveVect(MMG_pMesh ,char *); + +#ifdef __cplusplus +namespace mmg3d{ +extern "C" { +#endif +int MMG_mmg3dlib(int opt[9],MMG_pMesh mesh,MMG_pSol sol); +#ifdef __cplusplus +}} +#endif diff --git a/contrib/mmg3d/build/sources/libmmg3d_internal.h b/contrib/mmg3d/build/sources/libmmg3d_internal.h new file mode 100644 index 0000000000..67be6768cb --- /dev/null +++ b/contrib/mmg3d/build/sources/libmmg3d_internal.h @@ -0,0 +1,59 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +typedef MMG_Point Point; +typedef MMG_Tetra Tetra; +typedef MMG_Tria Tria; +typedef MMG_Displ Displ; +typedef MMG_Mesh Mesh; +typedef MMG_Sol Sol; + +typedef MMG_pPoint pPoint; +typedef MMG_pTetra pTetra; +typedef MMG_pDispl pDispl; +typedef MMG_pTria pTria; +typedef MMG_Info Info; +typedef MMG_pMesh pMesh; +typedef MMG_pSol pSol; diff --git a/contrib/mmg3d/build/sources/librnbg.c b/contrib/mmg3d/build/sources/librnbg.c new file mode 100644 index 0000000000..bacfb4940b --- /dev/null +++ b/contrib/mmg3d/build/sources/librnbg.c @@ -0,0 +1,461 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* librnbg + * + * Written by Cedric Lachat + */ +#include "mesh.h" + +#ifdef USE_SCOTCH + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include "librnbg.h" + +#define CHECK_SCOTCH(t,m,e) if(0!=t){perror(m);exit(e);} + + + + +/* Internal function : biPartBoxCompute + * it computes a new numbering of graph vertices, using a bipartitioning. + * + * - graf : the input graph + * - vertNbr : the number of vertices + * - boxVertNbr : the number of vertices of each box + * - permVrtTab : the new numbering + * + * returning 0 if OK, 1 else + */ +int biPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) { + int boxNbr, vertIdx, boxIdx; + SCOTCH_Num tmp, tmp2, *partTab, *partNumTab, *partPrmTab; + SCOTCH_Strat strat ; + + /* Computing the number of boxes */ + boxNbr = vertNbr / boxVertNbr; + if (boxNbr * boxVertNbr != vertNbr) { + boxNbr = boxNbr + 1; + } + + + /* Initializing SCOTCH functions */ + CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; + CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, "r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}|m{type=h,vert=80,low=h{pass=10}f{bal=0.005,move=0},asc=b{bnd=f{bal=0.05,move=0},org=f{bal=0.05,move=0}}}}"), "scotch_stratGraphMap", 0) ; + + partTab = (SCOTCH_Num *)M_calloc(vertNbr, sizeof(SCOTCH_Num), "boxCompute"); + + + /* Partionning the graph */ + CHECK_SCOTCH(SCOTCH_graphPart(&graf, boxNbr, &strat, partTab), "scotch_graphPart", 0); + + partNumTab = (SCOTCH_Num *)M_calloc(boxNbr, sizeof(SCOTCH_Num), "boxCompute"); + + if (!memset(partNumTab, 0, boxNbr*sizeof(SCOTCH_Num))) { + perror("memset"); + return 0; + } + + /* Computing the number of elements of each box */ + for( vertIdx = 0 ; vertIdx< vertNbr ;vertIdx++) + partNumTab[partTab[vertIdx]] += 1; + + + /* partition permutation tabular */ + partPrmTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "boxCompute"); + + + /* Copying the previous tabular in order to have the index of the first + * element of each box + * */ + tmp = partNumTab[0]; + partNumTab[0] = 0; + for(boxIdx = 1; boxIdx < boxNbr ; boxIdx++) { + tmp2 = partNumTab[boxIdx]; + partNumTab[boxIdx] = partNumTab[boxIdx-1] + tmp; + tmp = tmp2; + } + + /* partPrmTab is built such as each vertex belongs to his box */ + for( vertIdx = 0;vertIdx< vertNbr;vertIdx++) + partPrmTab[partNumTab[partTab[vertIdx]]++] = vertIdx; + + + /* Infering the new numbering */ + for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) + permVrtTab[partPrmTab[vertIdx] + 1] = vertIdx + 1; + + M_free(partTab); + M_free(partNumTab); + M_free(partPrmTab); + + SCOTCH_stratExit(&strat) ; + return 0; +} + + + + +/* Internal function : kPartBoxCompute + * it computes a new numbering of graph vertices, using a k-partitioning. + * Assuming that baseval of the graph is 1 + * + * - graf : the input graph + * - vertNbr : the number of vertices + * - boxVertNbr : the number of vertices of each box + * - permVrtTab : the new numbering + * + * returning 0 if OK, 1 else + */ +int kPartBoxCompute(SCOTCH_Graph graf, int vertNbr, int boxVertNbr, SCOTCH_Num *permVrtTab) { + int boxNbr, vertIdx; + SCOTCH_Num logMaxVal, SupMaxVal, InfMaxVal, maxVal; + char s[200]; + SCOTCH_Num *sortPartTb; + SCOTCH_Strat strat ; + SCOTCH_Arch arch; + + /* Computing the number of boxes */ + boxNbr = vertNbr / boxVertNbr; + if (boxNbr * boxVertNbr != vertNbr) { + boxNbr = boxNbr + 1; + } + + + /* Initializing SCOTCH functions */ + CHECK_SCOTCH(SCOTCH_stratInit(&strat), "scotch_stratInit", 0) ; + CHECK_SCOTCH(SCOTCH_archVcmplt(&arch), "scotch_archVcmplt", 0) ; + + sprintf(s, "m{vert=%d,low=r{job=t,map=t,poli=S,sep=m{type=h,vert=80,low=h{pass=10}f{bal=0.0005,move=80},asc=f{bal=0.005,move=80}}}}", vertNbr / boxVertNbr); + CHECK_SCOTCH(SCOTCH_stratGraphMap(&strat, s), "scotch_stratGraphMap", 0) ; + + + sortPartTb= (SCOTCH_Num *)M_calloc(2*vertNbr, sizeof(SCOTCH_Num), "boxCompute"); + + + /* Partionning the graph */ + CHECK_SCOTCH(SCOTCH_graphMap(&graf, &arch, &strat, sortPartTb), "scotch_graphMap", 0); + + + // Looking for the max value in sortPartTb and computing sortPartTb as + // followed : + // - sortPartTb[2i] is the box value + // - sortPartTb[2i+1] is the vertex number + maxVal = sortPartTb[0]; + for (vertIdx = vertNbr - 1 ; vertIdx >= 0 ; vertIdx--) { + sortPartTb[2*vertIdx] = sortPartTb[vertIdx]; + sortPartTb[2*vertIdx+1] = vertIdx + 1; + if (sortPartTb[vertIdx] > maxVal) + maxVal = sortPartTb[vertIdx]; + } + + // Determining the log of MaxVal + logMaxVal = 0; + while ( maxVal > 0) { + logMaxVal++; + maxVal >>= 1; + } + + // Infering the interval in which box values will be + InfMaxVal = logMaxVal << logMaxVal; + SupMaxVal = (logMaxVal << (logMaxVal + 1)) - 1; + + // Increasing box values until they are in the previous interval + for (vertIdx = 0 ; vertIdx < vertNbr ; vertIdx++) { + while (!(sortPartTb[2*vertIdx] >= InfMaxVal && sortPartTb[2*vertIdx] <= SupMaxVal)) { + sortPartTb[2*vertIdx] <<= 1; + } + } + + + + // Sorting the tabular, which contains box values and vertex numbers + _SCOTCHintSort2asc1(sortPartTb, vertNbr); + + + /* Infering the new numbering */ + for (vertIdx = 0; vertIdx < vertNbr ; vertIdx++) { + permVrtTab[sortPartTb[2*vertIdx + 1]] = vertIdx + 1; + } + + SCOTCH_stratExit(&strat) ; + SCOTCH_archExit(&arch) ; + + M_free(sortPartTb); + + return 0; +} + + + +/* Function : renumbering + * it modifies the numbering of each node to prevent from cache missing. + * + * - boxVertNbr : number of vertices by box + * - mesh : the input mesh which is modified + * + * returning 0 if OK, 1 else + */ +int renumbering(int boxVertNbr, MMG_pMesh mesh, MMG_pSol sol) { + MMG_pPoint ppt; + MMG_pPoint points; + MMG_pTria ptri, trias; + MMG_pTetra ptet, tetras; + SCOTCH_Num edgeNbr; + SCOTCH_Num *vertTab, *vendTab, *edgeTab, *permVrtTab; + SCOTCH_Graph graf ; + int vertNbr, nodeGlbIdx, triaIdx, tetraIdx, ballTetIdx; + int i, j, k, addrNew, addrOld; + int edgeSiz; + int *vertOldTab, *permNodTab, ntreal, nereal, npreal; + int *adja,iadr; + double *metNew; + + + /* Computing the number of vertices and a contiguous tabular of vertices */ + vertNbr = 0; + vertOldTab = (int *)M_calloc(mesh->ne + 1, sizeof(int), "renumbering"); + + if (!memset(vertOldTab, 0, sizeof(int)*(mesh->ne+1))) { + perror("memset"); + return 1; + } + + for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { + + /* Testing if the tetra exists */ + if (!mesh->tetra[tetraIdx].v[0]) continue; + vertOldTab[tetraIdx] = vertNbr+1; + vertNbr++; + } + + + /* Allocating memory to compute adjacency lists */ + vertTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); + + if (!memset(vertTab, ~0, sizeof(SCOTCH_Num)*(vertNbr + 1))) { + perror("memset"); + return 1; + } + + vendTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); + + edgeNbr = 1; + edgeSiz = vertNbr*2; + edgeTab = (SCOTCH_Num *)M_calloc(edgeSiz, sizeof(SCOTCH_Num), "renumbering"); + + + + /* Computing the adjacency list for each vertex */ + for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { + + /* Testing if the tetra exists */ + if (!mesh->tetra[tetraIdx].v[0]) continue; + + + + + + iadr = 4*(tetraIdx-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + ballTetIdx = adja[i] >> 2; + + if (!ballTetIdx) continue; + + + + + + + /* Testing if one neighbour of tetraIdx has already been added */ + if (vertTab[vertOldTab[tetraIdx]] < 0) + vertTab[vertOldTab[tetraIdx]] = edgeNbr; + vendTab[vertOldTab[tetraIdx]] = edgeNbr+1; + + /* Testing if edgeTab memory is enough */ + if (edgeNbr >= edgeSiz) { + edgeSiz += EDGEGAP; + edgeTab = (SCOTCH_Num *)M_realloc(edgeTab, edgeSiz * sizeof(SCOTCH_Num), "renumbering"); + } + + edgeTab[edgeNbr++] = vertOldTab[ballTetIdx]; + } + } + + edgeNbr--; + + + /* Building the graph by calling Scotch functions */ + + SCOTCH_graphInit(&graf) ; + CHECK_SCOTCH(SCOTCH_graphBuild(&graf, (SCOTCH_Num) 1, vertNbr, vertTab+1, vendTab+1, NULL, NULL, edgeNbr, edgeTab+1, NULL), "scotch_graphbuild", 0) ; + CHECK_SCOTCH(SCOTCH_graphCheck(&graf), "scotch_graphcheck", 0) ; + + permVrtTab = (SCOTCH_Num *)M_calloc(vertNbr + 1, sizeof(SCOTCH_Num), "renumbering"); + + CHECK_SCOTCH(kPartBoxCompute(graf, vertNbr, boxVertNbr, permVrtTab), "boxCompute", 0); + + SCOTCH_graphExit(&graf) ; + + M_free(vertTab); + M_free(vendTab); + M_free(edgeTab); + + + permNodTab = (int *)M_calloc(mesh->np + 1, sizeof(int), "renumbering"); + + /* Computing the new point list and modifying the sol structures*/ + tetras = (MMG_pTetra)M_calloc(mesh->nemax+1,sizeof(MMG_Tetra),"renumbering"); + + points = (MMG_pPoint)M_calloc(mesh->npmax+1,sizeof(MMG_Point),"renumbering"); + + metNew = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"renumbering"); + + nereal = 0; + npreal = 1; + for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { + ptet = &mesh->tetra[tetraIdx]; + + /* Testing if the tetra exists */ + if (!ptet->v[0]) continue; + + /* Building the new point list */ + tetras[permVrtTab[vertOldTab[tetraIdx]]] = *ptet; + nereal++; + + for(j = 0 ; j <= 3 ; j++) { + + nodeGlbIdx = mesh->tetra[tetraIdx].v[j]; + + if (permNodTab[nodeGlbIdx]) continue; + + ppt = &mesh->point[nodeGlbIdx]; + + if (!(ppt->tag & M_UNUSED)) { + /* Building the new point list */ + permNodTab[nodeGlbIdx] = npreal++; + + points[permNodTab[nodeGlbIdx]] = *ppt; + + /* Building the new sol met */ + addrOld = (nodeGlbIdx-1)*sol->offset + 1; + addrNew = (permNodTab[nodeGlbIdx]-1)*sol->offset + 1; + memcpy(&metNew[addrNew], &sol->met[addrOld], sol->offset*sizeof(double)); + } + } + } + + + M_free(mesh->tetra); + mesh->tetra = tetras; + mesh->ne = nereal; + + M_free(mesh->point); + mesh->point = points; + mesh->np = npreal - 1; + + M_free(sol->met); + sol->met = metNew; + + trias = (MMG_pTria)M_calloc(mesh->ntmax+1,sizeof(MMG_Tria),"renumbering"); + + ntreal = 1; + for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) { + ptri = &mesh->tria[triaIdx]; + + /* Testing if the tetra exists */ + if (!ptri->v[0]) continue; + + /* Building the new point list */ + trias[ntreal] = *ptri; + ntreal++; + } + + M_free(mesh->tria); + mesh->tria = trias; + mesh->nt = ntreal - 1; + + mesh->npnil = mesh->np + 1; + mesh->nenil = mesh->ne + 1; + + for (k=mesh->npnil; k<mesh->npmax-1; k++) + mesh->point[k].tmp = k+1; + + for (k=mesh->nenil; k<mesh->nemax-1; k++) + mesh->tetra[k].v[3] = k+1; + + if ( mesh->nt ) { + mesh->ntnil = mesh->nt + 1; + for (k=mesh->ntnil; k<mesh->ntmax-1; k++) + mesh->tria[k].v[2] = k+1; + } + + + + /* Modifying the numbering of the nodes of each tetra */ + for(tetraIdx = 1 ; tetraIdx < mesh->ne + 1 ; tetraIdx++) { + if (!mesh->tetra[tetraIdx].v[0]) continue; + for(j = 0 ; j <= 3 ; j++) { + mesh->tetra[tetraIdx].v[j] = permNodTab[mesh->tetra[tetraIdx].v[j]]; + } + } + + /* Modifying the numbering of the nodes of each triangle */ + for(triaIdx = 1 ; triaIdx < mesh->nt + 1 ; triaIdx++) { + if (!mesh->tria[triaIdx].v[0]) continue; + for(j = 0 ; j <= 2 ; j++) { + mesh->tria[triaIdx].v[j] = permNodTab[mesh->tria[triaIdx].v[j]]; + } + } + + M_free(permVrtTab); + + return 1; +} +#endif \ No newline at end of file diff --git a/contrib/mmg3d/build/sources/librnbg.h b/contrib/mmg3d/build/sources/librnbg.h new file mode 100644 index 0000000000..97639a447c --- /dev/null +++ b/contrib/mmg3d/build/sources/librnbg.h @@ -0,0 +1,68 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* librnbg +* +* Written by Cedric Lachat +*/ +#ifdef USE_SCOTCH + +#ifndef __RENUM__ +#define __RENUM__ + +#include <scotch.h> + +#define HASHPRIME 37 +#define EDGEGAP 100 + +typedef struct MeshGraphHash_ { + int vertNum; + int vertEnd; +} MeshGraphHash; + +int renumbering(int vertBoxNbr, MMG_pMesh mesh, MMG_pSol sol) ; + +#endif /* __RENUM__ */ +#endif \ No newline at end of file diff --git a/contrib/mmg3d/build/sources/locate.c b/contrib/mmg3d/build/sources/locate.c new file mode 100644 index 0000000000..c01826d9dc --- /dev/null +++ b/contrib/mmg3d/build/sources/locate.c @@ -0,0 +1,141 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define EPST -1.e-14 +#define EPSR 1.e+14 + + +/* find tetra containg p, starting nsdep */ +int MMG_loctet(pMesh mesh,int nsdep,int base,double *p,double *cb) { + pTetra pt; + pPoint p0,p1,p2,p3; + double bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz; + double epsra,vol1,vol2,vol3,vol4,dd; + int *adj,iadr,it,nsfin; + + it = 0; + nsfin = nsdep; + /*printf("locateTetra: searching for %f %f %f , init %d\n",p[0],p[1],p[2],nsdep);*/ + do { + if ( !nsfin ) return(0); + pt = &mesh->tetra[nsfin]; + if ( !pt->v[0] ) return(0); + if ( pt->mark == base ) return(0); + pt->mark = base; + iadr = 4*(nsfin-1)+1; + adj = &mesh->adja[iadr]; + p0 = &mesh->point[pt->v[0]]; + p1 = &mesh->point[pt->v[1]]; + p2 = &mesh->point[pt->v[2]]; + p3 = &mesh->point[pt->v[3]]; + + /* barycentric */ + bx = p1->c[0] - p0->c[0]; + by = p1->c[1] - p0->c[1]; + bz = p1->c[2] - p0->c[2]; + cx = p2->c[0] - p0->c[0]; + cy = p2->c[1] - p0->c[1]; + cz = p2->c[2] - p0->c[2]; + dx = p3->c[0] - p0->c[0]; + dy = p3->c[1] - p0->c[1]; + dz = p3->c[2] - p0->c[2]; + + /* test volume */ + vx = cy*dz - cz*dy; + vy = cz*dx - cx*dz; + vz = cx*dy - cy*dx; + + epsra = EPST*(bx*vx + by*vy + bz*vz); + apx = p[0] - p0->c[0]; + apy = p[1] - p0->c[1]; + apz = p[2] - p0->c[2]; + + /* p in 2 */ + vol2 = apx*vx + apy*vy + apz*vz; + if ( epsra > vol2 ) { + nsfin = adj[1]/4; + continue; + } + + /* p in 3 */ + vx = by*apz - bz*apy; + vy = bz*apx - bx*apz; + vz = bx*apy - by*apx; + vol3 = dx*vx + dy*vy + dz*vz; + if ( epsra > vol3 ) { + nsfin = adj[2]/4; + continue; + } + + /* p in 4 */ + vol4 = -cx*vx - cy*vy - cz*vz; + if ( epsra > vol4 ) { + nsfin = adj[3]/4; + continue; + } + + /* p in 1 */ + vol1 = -epsra * EPSR - vol2 - vol3 - vol4; + if ( epsra > vol1 ) { + nsfin = adj[0]/4; + continue; + } + + dd = vol1+vol2+vol3+vol4; + if ( dd != 0.0 ) dd = 1.0 / dd; + cb[0] = vol1 * dd; + cb[1] = vol2 * dd; + cb[2] = vol3 * dd; + cb[3] = vol4 * dd; + + return(nsfin); + } + while ( ++it <= mesh->ne ); + + return(0); +} + diff --git a/contrib/mmg3d/build/sources/matrix.c b/contrib/mmg3d/build/sources/matrix.c new file mode 100644 index 0000000000..d09a8212ee --- /dev/null +++ b/contrib/mmg3d/build/sources/matrix.c @@ -0,0 +1,96 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#define EPS3 1.e-42 +#define EPS 1e-6 + +/* invert 3x3 symmetric matrix */ +int MMG_invmat(double *m,double *mi) { + double aa,bb,cc,det,vmin,vmax,maxx; + int k; + + /* check diagonal matrices */ + vmax = fabs(m[1]); + maxx = fabs(m[2]); + if( maxx > vmax ) vmax = maxx; + maxx = fabs(m[4]); + if( maxx > vmax ) vmax = maxx; + if ( vmax < EPS ) { + mi[0] = 1./m[0]; + mi[3] = 1./m[3]; + mi[5] = 1./m[5]; + mi[1] = mi[2] = mi[4] = 0.0; + return(1); + } + + /* check ill-conditionned matrix */ + vmin = vmax = fabs(m[0]); + for (k=1; k<6; k++) { + maxx = fabs(m[k]); + if ( maxx < vmin ) vmin = maxx; + else if ( maxx > vmax ) vmax = maxx; + } + if ( vmax == 0.0 ) return(0); + /* compute sub-dets */ + aa = m[3]*m[5] - m[4]*m[4]; + bb = m[4]*m[2] - m[1]*m[5]; + cc = m[1]*m[4] - m[2]*m[3]; + det = m[0]*aa + m[1]*bb + m[2]*cc; + if ( fabs(det) < EPS3 ) return(0); + det = 1.0 / det; + + mi[0] = aa*det; + mi[1] = bb*det; + mi[2] = cc*det; + mi[3] = (m[0]*m[5] - m[2]*m[2])*det; + mi[4] = (m[1]*m[2] - m[0]*m[4])*det; + mi[5] = (m[0]*m[3] - m[1]*m[1])*det; + + return(1); +} diff --git a/contrib/mmg3d/build/sources/memory.c b/contrib/mmg3d/build/sources/memory.c new file mode 100644 index 0000000000..9219eb3d56 --- /dev/null +++ b/contrib/mmg3d/build/sources/memory.c @@ -0,0 +1,284 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* file : memory.c + * C code for memory debugging, to be used in lieu + * of standard memory functions +*/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "memory.h" + + +typedef struct memstack { + size_t size; + void *ptr; + int nxt; + char call[30]; +} Memstack; + +typedef Memstack * pMemstack; + +const int MAXMEM = 300; +pMemstack mstack; +int stack,cur; + + +int M_memLeak() { + int i,c=0; + + for (i=1; i<=MAXMEM; i++) + if (mstack[i].ptr) c++; + return(c); +} + +/* print out allocated pointers */ +void M_memDump() { + size_t size; + int i,c; + static long mega = 1024 * 1024; + static long kilo = 1024; + + fprintf(stdout,"\n -- MEMORY USAGE\n"); + fprintf(stdout," Allocated pointers\n"); + size = 0; + c = 0; + for (i=1; i<=MAXMEM; i++) + if ( mstack[i].ptr ) { + fprintf(stdout," %3d %3d Pointer %10p size ",++c,i,mstack[i].ptr); + if (mstack[i].size > mega) + fprintf(stdout," %10d Mbytes ",(int)(mstack[i].size/mega)); + else if (mstack[i].size > kilo) + fprintf(stdout," %10d Kbytes ",(int)(mstack[i].size/kilo)); + else + fprintf(stdout," %10d bytes ",(int)(mstack[i].size)); + fprintf(stdout,"(%s)\n",mstack[i].call); + size += mstack[i].size; + } + fprintf(stdout," Memory leaks "); + if ( size > mega ) + fprintf(stdout," %10d Mbytes %d pointers\n",(int)(size/mega),c); + else if ( size > kilo ) + fprintf(stdout," %10d Kbytes %d pointers\n",(int)(size/kilo),c); + else if ( size ) + fprintf(stdout," %10d bytes %d pointers\n",(int)size,c); +} + +/* Returns allocated memory space in bytes */ +size_t M_memSize() { + size_t size; + int i; + + size = 0; + for (i=1; i<=MAXMEM; i++) + if ( mstack[i].ptr ) + size += mstack[i].size; + return size; +} + +/* Allocates space for a block of at least size bytes, + but does not initialize the space. */ +void *M_malloc(size_t size,char *call) { + int i; + + /* check if first call */ + if ( !mstack ) { + mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack)); + assert(mstack); + for (i=1; i<MAXMEM; i++) + mstack[i].nxt = i+1; + cur = 1; + stack = 0; + } + + /* store pointer, size */ + if ( stack < MAXMEM ) { + mstack[cur].ptr = malloc(size); + assert(mstack[cur].ptr); + mstack[cur].size = size; + /* i.e. mstack[cur].call = strdup(call) */ + /* mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char)); + assert(mstack[cur].call); */ + strncpy(mstack[cur].call,call,19); + i = cur; + cur = mstack[cur].nxt; + ++stack; +#ifdef MEMDEBUG + fprintf(stdout,"M_malloc: allocate %p of size %10d (%g,%d)\n", + mstack[cur].ptr,size,stack,cur); +#endif + return(mstack[i].ptr); + } + else { + fprintf(stderr,"M_malloc: unable to store %10Zd bytes pointer. table full\n", + size); + return(0); + } +} + + +/* Allocates space for an array of nelem elements, each of size + elsize bytes, and initializes the space to zeros. + Actual amount of space allocated is >= nelem * elsize bytes. */ +void *M_calloc(size_t nelem, size_t elsize,char *call) { + int i; + + /* check if first call */ + if ( !mstack ) { + mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack)); + assert(mstack); + for (i=1; i<MAXMEM; i++) + mstack[i].nxt = i+1; + cur = 1; + stack = 0; + } + + /* store pointer, size */ + if ( stack < MAXMEM ) { + mstack[cur].ptr = calloc(nelem,elsize); + if ( !mstack[cur].ptr ) return(0); + + /*assert(mstack[cur].ptr);*/ + mstack[cur].size = nelem * elsize; + /* mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char)); + assert(mstack[cur].call); */ + strncpy(mstack[cur].call,call,19); + i = cur; + cur = mstack[cur].nxt; + ++stack; +#ifdef MEMDEBUG + fprintf(stdout,"M_calloc: allocate %p of size %d (%d,%d)\n", + mstack[cur].ptr,nelem*elsize,stack,cur); +#endif + return(mstack[i].ptr); + } + else { + fprintf(stderr,"M_calloc: unable to allocate %10Zd bytes. table full\n", + nelem*elsize); + return(0); + } +} + +/* Changes the size of the block pointed to by ptr to size bytes + and returns a pointer to the (possibly moved) block. Existing + contents are unchanged up to the lesser of the new and old sizes. */ +void *M_realloc(void *ptr, size_t size,char *call) { + int i; + + if ( !ptr ) + return 0; + + for (i=1; i<=MAXMEM; i++) { + if (ptr == mstack[i].ptr) { + /* free(mstack[i].call); + mstack[cur].call = (char*)malloc((strlen(call)+1) * sizeof(char)); + assert(mstack[cur].call); */ + strncpy(mstack[i].call,call,19); + mstack[i].ptr = realloc(mstack[i].ptr,size); + if (size) + assert(mstack[i].ptr); + mstack[i].size = size; +#ifdef MEMDEBUG + fprintf(stdout,"M_realloc: reallocate %p of size %d (%d)\n", + mstack[i].ptr,mstack[i].size,size); +#endif + return(mstack[i].ptr); + } + } +#ifdef MEMDEBUG + fprintf(stderr,"M_realloc: pointer %p not found\n",ptr); +#endif + return(0); +} + +/* Deallocates the space pointed to by ptr (a pointer to a block + previously allocated by malloc() and makes the space available + for further allocation. If ptr is NULL, no action occurs. */ +void M_free(void *ptr) { + int i; + + assert(ptr); + for (i=1; i<=MAXMEM; i++) { + if (mstack[i].ptr && ptr == mstack[i].ptr) { + --stack; + free(mstack[i].ptr); + mstack[i].ptr = 0; + mstack[i].size = 0; + mstack[i].nxt = cur; + mstack[i].call[0] = '\0'; + cur = i; +#ifdef MEMDEBUG + fprintf(stdout,"M_free: deallocate %p of size %d (%d,%d)\n", + ptr,mstack[i].size,stack,cur); +#endif + return; + } + } +#ifdef MEMDEBUG + fprintf(stderr,"M_free: pointer %p not found\n",ptr); +#endif +} + + +/* dump memory requirements */ +void primem(int np) { + int memsize; + + memsize = M_memSize(); + if ( memsize ) { + fprintf(stdout,"\n -- MEMORY REQUIREMENTS\n"); + if (memsize > 1024*1024) + fprintf(stdout," Total size : %10Zd Mbytes", + (long int)(memsize/(1024.*1024.))); + else if (memsize > 1024) + fprintf(stdout," Total size : %10Zd Kbytes",(long int)(memsize/1024.)); + else + fprintf(stdout," Total size : %10Zd bytes ",(long int)memsize); + fprintf(stdout," (i.e. %d bytes/point)\n",memsize / np); + } +} diff --git a/contrib/mmg3d/build/sources/memory.h b/contrib/mmg3d/build/sources/memory.h new file mode 100644 index 0000000000..dc85346434 --- /dev/null +++ b/contrib/mmg3d/build/sources/memory.h @@ -0,0 +1,67 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdlib.h> +#include <assert.h> + +/* prototype (re)definitions */ +void *M_malloc(size_t size,char *call); +void *M_calloc(size_t nelem,size_t elsize,char *call); +void *M_realloc(void *ptr, size_t size,char *call); +void M_free(void *ptr); + +/* ptototypes : tools */ +int M_memLeak(); +void M_memDump(); +size_t M_memSize(); + + +#ifdef __cplusplus +} +#endif diff --git a/contrib/mmg3d/build/sources/mesh.h b/contrib/mmg3d/build/sources/mesh.h new file mode 100644 index 0000000000..efa8ae9ccf --- /dev/null +++ b/contrib/mmg3d/build/sources/mesh.h @@ -0,0 +1,411 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#ifndef _MMG3D_H +#define _MMG3D_H + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <ctype.h> +#include <math.h> +#include <float.h> + + +#include "chrono.h" +#include "memory.h" + +#include "libmmg3d.h" +#include "libmmg3d_internal.h" +#include "mmg3dConfig.h" +#include "eigenv.h" + +#define M_VER "4.0 c" +#define M_REL "July 20, 2010" +#define M_STR "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" + +#define EPS 1.e-06 +#define EPS1 1.e-9 +#define EPS2 1.e-12 +#define EPSOK 1.e-18 +#define EPS30 1.e-30 + +#define ALPHAC 0.20412415 /* sqrt(6)/12 */ +#define ALPHAD 0.04811252 /* 1.0/(12*sqrt(3)) */ +#define BETAC 0.03928371 /* sqrt(2)/36 */ +#define CALLIM 1.E+35 /*valeur de la qual pire*/ + + +#define LLONG 1.41 +#define LSHORT 0.68 +#define LFILT 0.7 +#define QDEGRAD 2.45 + +#define LONMAX 4096//512 +#define NPMAX 500000 +#define NTMAX 1000000 +#define NEMAX 3000000 + +#define PRECI 1 +#define BUCKSIZ 64 + +#define M_MIN(a,b) ( (a) < (b) ? (a) : (b) ) +#define M_MAX(a,b) ( (a) < (b) ? (b) : (a) ) + +#define M_NOTAG (0) +#define M_UNUSED (1 << 0) +#define M_BDRY (1 << 1) +#define M_MOVE (1 << 2) +#define M_CAVITY (1 << 3) +#define M_CORNER (1 << 4) +#define M_REQUIRED (1 << 5) +#define M_RIDGE_GEO (1 << 6) +#define M_RIDGE_REF (1 << 7) +#define ALL_BDRY 63 + +/*#ifdef INT_MAX +#undef INT_MAX +#undef SHORT_MAX +#endif +*/#define INT_MAX 0x7fffffff +#define SHORT_MAX 0x7fff + + +extern unsigned char MMG_idir[4][3]; +extern unsigned char MMG_inxt[7]; +extern unsigned char MMG_iarf[4][3]; +extern unsigned char MMG_iare[6][2]; +extern unsigned char MMG_ifar[6][2]; +extern unsigned char MMG_isar[6][2]; +extern unsigned char MMG_arpt[4][3]; + + +typedef struct { + int min,max,iel,nxt; +} hedge; +typedef struct { + int size,nhmax,hnxt; + hedge *item; +} Hedge; +typedef Hedge * pHedge; + +typedef struct { + int *blay,*blref,nblay; +} Blayer; + + +typedef struct slist { + Hedge hedg; + double qual[LONMAX+1]; + int tetra[LONMAX+1]; +} List; +typedef List * pList; + +typedef struct squeue { + int *stack,cur; +} Queue; +typedef Queue * pQueue; + +typedef struct { + int size,curc; + int *cell; + int *link; +} Heap; +typedef Heap * pHeap; + +typedef struct { + int size; + int *head; + int *link; +} Bucket; +typedef Bucket * pBucket; + +/*basic*/ +int MMG_setfunc(int ); + +int MMG_cutprism(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int ref); +int MMG_cuthex(pMesh mesh,pHedge hed,int k,int p0,int p1,int p2,int p3,int p4,int p5,int p6,int p7, int ref); + +int MMG_analar(pMesh ,pSol ,pBucket ,int *,int *,int *,int *); +int MMG_analarcutting(pMesh ,pSol ,pHedge ,int *,double* ,double ); +int MMG_boulep(pMesh ,int ,int ,pList ); +int MMG_bouleg(pMesh ,int ,int ,pList ); +int MMG_coquil(pMesh ,int ,int ,pList ); +int MMG_cendel(pMesh ,pSol ,double ,int ); +int MMG_spledg(pMesh ,pSol ,pQueue ,pList ,int ,double ,double ); + +int MMG_interp_ani(double *,double *,double *,double ); +int MMG_interplog(double *,double *,double *,double *,double ); +int MMG_interp_iso(double *,double *,double *,double ); + +/* delaunay */ +int MMG_correction(pMesh ,int ,pList ,int ,int ,char ); +int MMG_delone(pMesh ,pSol ,int ,pList ,int ); +int MMG_delons(pMesh ,pSol ,pQueue ,int ,pList ,int ,double ); +int MMG_cenrad_ani(pMesh ,double * ,double *,double *,double *); +int MMG_cenrad_iso(pMesh ,double * ,double *,double *); + +/*pattern*/ +int MMG_pattern1(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern2(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern3(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern4(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern5(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern6(pMesh ,pSol ,int ,int* ); +int MMG_pattern22(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern31(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern32(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern33(pMesh ,pSol ,pHedge ,int ); +int MMG_pattern41(pMesh ,pSol ,pHedge ,int ); + +int MMG_colpoi(pMesh ,pSol ,int ,int ,int ,double ); + +/* hash */ +int MMG_hashTetra(pMesh ); +int MMG_hashEdge(pMesh ,pHedge ,int ,int ,int *); +int MMG_inEdge(pHedge ,int *,int *,int *); +int MMG_markBdry(pMesh ); +int MMG_edgePoint(pHedge ,int ,int ); +int MMG_edgePut(pHedge ,int ,int ,int ); + + +int MMG_loctet(pMesh ,int ,int ,double *,double *); +int MMG_computeMetric(pMesh ,pSol ,int ,double * ); + +/* scale */ +int MMG_doSol(pMesh ,pSol ); +int MMG_scaleMesh(pMesh ,pSol ); +int MMG_unscaleMesh(pMesh ,pSol ); + +int MMG_mmg3d1(pMesh ,pSol ,int *); +int MMG_mmg3d9(pMesh ,pSol ,int *); +int MMG_mmg3d4(pMesh ,pSol ,int *); + +/* zaldy */ +int MMG_newPt(pMesh ,double *c); +int MMG_newElt(pMesh ); +int MMG_getnElt(pMesh ,int ); +int MMG_newTria(pMesh ); +void MMG_delPt(pMesh ,int ); +void MMG_delElt(pMesh ,int ); +void MMG_delTria(pMesh ,int ); +int MMG_zaldy(pMesh ); +int MMG_zaldy3(pSol ); +int MMG_zaldy4(pHedge ,int ); + +int MMG_optra4(pMesh ,pSol ); +int MMG_optcoq(pMesh ,pSol); +int MMG_opttet(pMesh ,pSol); +int MMG_opttyp(pMesh ,pSol ,double ,int *); +int MMG_optbdry(pMesh ,pSol ,int ); +int MMG_opt2peau(pMesh ,pSol ,pQueue ,int ,double ); +int MMG_optlap(pMesh ,pSol ); + +/* swapar */ +int MMG_swapar(pMesh ,pSol ,pQueue ,List *,int ,double ,double ); + +int MMG_simu23(pMesh ,pSol ,int ,int ,double ); +int MMG_simu32(pMesh ,pSol ,pList ,double ); +int MMG_swap32(pMesh ,pSol ,pList ); +int MMG_swap23(pMesh ,pSol ,pQueue ,int ,int ,double ); + +int MMG_simu44(pMesh ,pSol ,pList ,double ); +int MMG_swap44_1(pMesh ,pSol ,pList ); +int MMG_swap44_2(pMesh ,pSol ,pList ); + +int MMG_simu56(pMesh ,pSol ,pList ,double ); +int MMG_swap56_1(pMesh ,pSol ,pList ); +int MMG_swap56_2(pMesh ,pSol ,pList ); +int MMG_swap56_3(pMesh ,pSol ,pList ); +int MMG_swap56_4(pMesh ,pSol ,pList ); +int MMG_swap56_5(pMesh ,pSol ,pList ); + +int MMG_simu68(pMesh ,pSol ,pList ,double ); +int MMG_swap68_1(pMesh ,pSol ,pList ); +int MMG_swap68_2(pMesh ,pSol ,pList ); +int MMG_swap68_3(pMesh ,pSol ,pList ); +int MMG_swap68_4(pMesh ,pSol ,pList ); +int MMG_swap68_5(pMesh ,pSol ,pList ); +int MMG_swap68_6(pMesh ,pSol ,pList ); +int MMG_swap68_7(pMesh ,pSol ,pList ); +int MMG_swap68_8(pMesh ,pSol ,pList ); +int MMG_swap68_9(pMesh ,pSol ,pList ); +int MMG_swap68_10(pMesh ,pSol ,pList ); +int MMG_swap68_11(pMesh ,pSol ,pList ); +int MMG_swap68_12(pMesh ,pSol ,pList ); +int MMG_swap68_13(pMesh ,pSol ,pList ); +int MMG_swap68_14(pMesh ,pSol ,pList ); + +int MMG_simu710(pMesh ,pSol ,pList ,double ); +int MMG_swap710_1(pMesh ,pSol ,pList ); +int MMG_swap710_2(pMesh ,pSol ,pList ); +int MMG_swap710_3(pMesh ,pSol ,pList ); +int MMG_swap710_4(pMesh ,pSol ,pList ); +int MMG_swap710_5(pMesh ,pSol ,pList ); +int MMG_swap710_6(pMesh ,pSol ,pList ); +int MMG_swap710_7(pMesh ,pSol ,pList ); +int MMG_swap710_8(pMesh ,pSol ,pList ); +int MMG_swap710_9(pMesh ,pSol ,pList ); +int MMG_swap710_10(pMesh ,pSol ,pList ); +int MMG_swap710_11(pMesh ,pSol ,pList ); +int MMG_swap710_12(pMesh ,pSol ,pList ); +int MMG_swap710_13(pMesh ,pSol ,pList ); +int MMG_swap710_14(pMesh ,pSol ,pList ); +int MMG_swap710_15(pMesh ,pSol ,pList ); +int MMG_swap710_16(pMesh ,pSol ,pList ); +int MMG_swap710_17(pMesh ,pSol ,pList ); +int MMG_swap710_18(pMesh ,pSol ,pList ); +int MMG_swap710_19(pMesh ,pSol ,pList ); +int MMG_swap710_20(pMesh ,pSol ,pList ); +int MMG_swap710_21(pMesh ,pSol ,pList ); +int MMG_swap710_22(pMesh ,pSol ,pList ); +int MMG_swap710_23(pMesh ,pSol ,pList ); +int MMG_swap710_24(pMesh ,pSol ,pList ); +int MMG_swap710_25(pMesh ,pSol ,pList ); +int MMG_swap710_26(pMesh ,pSol ,pList ); +int MMG_swap710_27(pMesh ,pSol ,pList ); +int MMG_swap710_28(pMesh ,pSol ,pList ); +int MMG_swap710_29(pMesh ,pSol ,pList ); +int MMG_swap710_30(pMesh ,pSol ,pList ); +int MMG_swap710_31(pMesh ,pSol ,pList ); +int MMG_swap710_32(pMesh ,pSol ,pList ); +int MMG_swap710_33(pMesh ,pSol ,pList ); +int MMG_swap710_34(pMesh ,pSol ,pList ); +int MMG_swap710_35(pMesh ,pSol ,pList ); +int MMG_swap710_36(pMesh ,pSol ,pList ); +int MMG_swap710_37(pMesh ,pSol ,pList ); +int MMG_swap710_38(pMesh ,pSol ,pList ); +int MMG_swap710_39(pMesh ,pSol ,pList ); +int MMG_swap710_40(pMesh ,pSol ,pList ); +int MMG_swap710_41(pMesh ,pSol ,pList ); +int MMG_swap710_42(pMesh ,pSol ,pList ); + +int MMG_typelt(pMesh ,int ,int *); + +/* quality */ +double MMG_voltet(pMesh ,int ); +double MMG_quickvol(double *,double *,double *,double *); +int MMG_prilen(pMesh ,pSol ); +int MMG_outqua(pMesh ,pSol ); +int MMG_outquacubic(pMesh ,pSol ); +double MMG_priworst(pMesh , pSol ); +int MMG_ratio(pMesh mesh, pSol sol,char* filename); + +int MMG_chkmsh(pMesh ,int ,int ); + +/* bucket */ +pBucket MMG_newBucket(pMesh ,int ); +int MMG_addBucket(pMesh ,pBucket ,int ); +int MMG_delBucket(pMesh ,pBucket ,int ); +void MMG_freeBucket(pBucket ); + +/* heap */ +Heap *MMG_hipini(pMesh ,int ,short ,double ,int ); +void MMG_hipfree(Heap *); +int MMG_hipput(pMesh ,Heap *,int ); +int MMG_hippop(pMesh ,Heap *); +void MMG_hiprep(pMesh ,Heap *,int ); +void MMG_hipdel(pMesh ,Heap *,int ); + +/* queue */ +pQueue MMG_kiuini(pMesh ,int ,double ,int ); +int MMG_kiupop(pQueue ); +int MMG_kiudel(pQueue ,int ); +int MMG_kiuput(pQueue ,int ); +void MMG_kiufree(pQueue ); + +/* matrices */ +int MMG_invmat(double *,double *); + +double MMG_calte3_ani(pMesh mesh,pSol sol,int iel); + +/* function pointers */ +double MMG_long_ani(double *,double *,double *,double *); +double MMG_long_iso(double *,double *,double *,double *); +double MMG_caltetcubic(pMesh mesh,pSol sol,int iel); +double MMG_caltetrao(pMesh mesh,pSol sol,int iel); +double MMG_caltet_ani(pMesh mesh,pSol sol,int iel); +double MMG_caltet_iso(pMesh mesh,pSol sol,int iel); +double MMG_calte1_iso(pMesh mesh,pSol sol,int iel); +double MMG_calte1_ani(pMesh mesh,pSol sol,int iel); +double MMG_callong(pMesh mesh,pSol sol,int iel); +int MMG_caltet2_iso(pMesh mesh,pSol sol,int iel,int ie,double ,double * caltab); +int MMG_caltet2_ani(pMesh mesh,pSol sol,int iel,int ie,double ,double * caltab); +int MMG_caltet2long_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab); +int MMG_caltet2long_iso(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab); +int MMG_buckin_ani(pMesh mesh,pSol sol,pBucket bucket,int ip); +int MMG_buckin_iso(pMesh mesh,pSol sol,pBucket bucket,int ip); +int MMG_cavity_ani(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon); +int MMG_cavity_iso(pMesh mesh,pSol sol,int iel,int ip,pList list,int lon); +int MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base); +int MMG_optlen_iso(pMesh mesh,pSol sol,double declic,int base); +int MMG_optlen_iso_new(pMesh mesh,pSol sol,double declic,int base); +int MMG_optlen_iso2(pMesh mesh,pSol sol,double declic); +int MMG_interp_ani(double *,double *,double * ,double ); +int MMG_interp_iso(double *,double *,double * ,double ); +int MMG_optlentet_ani(pMesh ,pSol ,pQueue ,double ,int ,int ); +int MMG_optlentet_iso(pMesh ,pSol ,pQueue ,double ,int ,int ); +int MMG_movevertex_ani(pMesh ,pSol ,int ,int ); +int MMG_movevertex_iso(pMesh ,pSol ,int ,int ); + + +/* function pointers */ +typedef int (*MMG_Swap)(pMesh ,pSol ,pList ); +MMG_Swap MMG_swpptr; +double (*MMG_length)(double *,double *,double *,double *); +double (*MMG_caltet)(pMesh ,pSol ,int ); +double (*MMG_calte1)(pMesh ,pSol ,int ); +int (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *); +int (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int ); +int (*MMG_buckin)(pMesh ,pSol ,pBucket ,int ); +int (*MMG_optlen)(pMesh ,pSol ,double ,int ); +int (*MMG_interp)(double *,double *,double *,double ); +int (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int ); +int (*MMG_movevertex)(pMesh ,pSol ,int ,int ); + + +#endif diff --git a/contrib/mmg3d/build/sources/mmg3d.c b/contrib/mmg3d/build/sources/mmg3d.c new file mode 100644 index 0000000000..b394a38a75 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3d.c @@ -0,0 +1,701 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "compil.date" +#include "mesh.h" +#include "eigenv.h" + +TIM_mytime MMG_ctim[TIMEMAX]; +short MMG_imprim; + +unsigned char MMG_idir[4][3] = { {1,2,3}, {0,3,2}, {0,1,3}, {0,2,1} }; +unsigned char MMG_inxt[7] = { 1,2,3,0,1,2,3 }; +unsigned char MMG_iarf[4][3] = { {5,4,3}, {5,1,2}, {4,2,0}, {3,0,1} }; +unsigned char MMG_iare[6][2] = { {0,1}, {0,2}, {0,3}, {1,2}, {1,3}, {2,3} }; +unsigned char MMG_ifar[6][2] = { {2,3}, {1,3}, {1,2}, {0,3}, {0,2}, {0,1} }; +unsigned char MMG_isar[6][2] = { {2,3}, {3,1}, {1,2}, {0,3}, {2,0}, {0,1} }; +unsigned char MMG_arpt[4][3] = { {0,1,2}, {0,4,3}, {1,3,5}, {2,5,4} }; + +static void excfun(int sigid) { + switch (sigid) { + case SIGFPE: + fprintf(stderr," ## FP EXCEPTION. STOP\n"); + break; + case SIGILL: + fprintf(stderr," ## ILLEGAL INSTRUCTION. STOP\n"); + break; + case SIGSEGV: + fprintf(stderr," ## SEGMENTATION FAULT. STOP\n"); + break; + case SIGABRT: + case SIGTERM: + case SIGINT: + fprintf(stderr," ## ABNORMAL END. STOP\n"); + break; + } + exit(1); +} + + +static void usage(char *prog) { + fprintf(stdout,"usage: %s [-v[n]] [-h] [-m n] [opts..] filein[.mesh] [-out fileout]\n",prog); + + fprintf(stdout,"\n** Generic options :\n"); + fprintf(stdout,"-d Turn on debug mode\n"); + fprintf(stdout,"-h Print this message\n"); + fprintf(stdout,"-v [n] Tune level of verbosity\n"); + fprintf(stdout,"-m [n] Set memory size to n Mbytes\n"); + + fprintf(stdout,"\n"); + fprintf(stdout,"-O [n] Optimization level\n"); + fprintf(stdout," 1 adaptation\n"); + fprintf(stdout," 4 use global splitting (warning modify boundary mesh)\n"); + fprintf(stdout," 9 moving mesh\n"); + fprintf(stdout," 10 transform an hexahedral/prism mesh in a tetrahedral mesh \n"); + fprintf(stdout," -n turn off optimisation\n"); + + fprintf(stdout,"\n** Misc. options\n"); + fprintf(stdout,"-bucket [n] Specify the size of bucket per dimension\n"); + fprintf(stdout,"-noswap no edge or face flipping\n"); + fprintf(stdout,"-nomove no point relocation\n"); + fprintf(stdout,"-noinsert no new point\n"); + //fprintf(stdout,"-bdry add points on boundary mesh\n"); + fprintf(stdout,"-out fileout Specify output file name\n"); +#ifdef USE_SCOTCH + fprintf(stdout,"-rn n num Specify the number of vertices by box to renumber nodes and the renumberings\n"); +#endif + fprintf(stdout,"-dt dt to compute the node speed\n"); + + exit(1); +} + + +static int parsar(int argc,char *argv[],pMesh mesh,pSol sol) { + int i; + Info *info; + char *ptr; + + info = &mesh->info; + + i = 1; + while ( i < argc ) { + if ( *argv[i] == '-' ) { + switch(argv[i][1]) { + case 'h': /* on-line help */ + case '?': + usage(argv[0]); + break; + + case 'b': + if ( !strcmp(argv[i],"-bucket") && i < argc-1 ) { + ++i; + if ( isdigit(argv[i][0]) ) + info->bucksiz = atoi(argv[i]); + else + i--; + } + else if ( !strcmp(argv[i],"-bdry") ){ + printf("-bdry option discarded\n"); + //info->bdry = 1; + } + else { + fprintf(stderr,"Missing argument option %s\n",argv[i]); + usage(argv[0]); + } + break; + + case 'd': /* debug */ + if ( !strcmp(argv[i],"-dt") ) { + ++i; + info->dt = atof(argv[i]); + } else { + info->ddebug = 1; + } + break; + + case 'i': + if ( !strcmp(argv[i],"-in") ) { + ++i; + mesh->name = argv[i]; + info->imprim = 5; + } + break; + + case 'm': /* memory */ + if ( !strcmp(argv[i],"-mov") ) { + ++i; + mesh->move = argv[i]; + } + else if ( ++i < argc ) { + if ( isdigit(argv[i][0]) ) + info->memory = atoi(argv[i]); + else + i--; + } + else { + fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]); + usage(argv[0]); + } + break; + + case 'n': + if ( !strcmp(argv[i],"-noswap") ) + info->noswap = 1; + else if( !strcmp(argv[i],"-noinsert") ) + info->noinsert = 1; + else if( !strcmp(argv[i],"-nomove") ) + info->nomove = 1; + break; + + case 'o': + if ( !strcmp(argv[i],"-out") ) { + ++i; + mesh->outf = argv[i]; + } + break; + + case 'O': /* option */ + if ( ++i < argc ) { + if ( (argv[i][0] == '-' && isdigit(argv[i][1])) || + argv[i][0] == '0' ) + info->option = atoi(argv[i]); + else if ( isdigit(argv[i][0]) ) + info->option = atoi(argv[i]); + else + i--; + } + break; + + case 's': + if ( !strcmp(argv[i],"-sol") ) { + ++i; + sol->name = argv[i]; + } + break; +#ifdef USE_SCOTCH + /* renumbering begin */ + case 'r': + if ( !strcmp(argv[i],"-rn") ) { + if ( ++i < argc ) { + if ( isdigit(argv[i][0]) ) + info->rn = atoi(argv[i]); + else { + fprintf(stderr,"Missing argument option %s\n",argv[i-1]); + usage(argv[0]); + } + if ( ++i < argc ) { + if ( isdigit(argv[i][0]) ) { + info->rn2 = atoi(argv[i]); + if (! ((info->rn2>=0) && (info->rn2<=3))){ + fprintf(stderr,"Wrong argument option %s\n",argv[i-1]); + usage(argv[0]); + } + } + else { + fprintf(stderr,"Missing argument option %s\n",argv[i-1]); + usage(argv[0]); + } + } + else { + fprintf(stderr,"Missing argument option %s\n",argv[i-1]); + usage(argv[0]); + } + } + else { + fprintf(stderr,"Missing argument option %s\n",argv[i-1]); + usage(argv[0]); + } + } + break; +/* renumbering end */ +#endif + case 'v': + if ( ++i < argc ) { + if ( argv[i][0] == '-' || isdigit(argv[i][0]) ) + info->imprim = atoi(argv[i]); + else + i--; + } + else { + fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]); + usage(argv[0]); + } + break; + + default: + fprintf(stderr," Unrecognized option %s\n",argv[i]); + usage(argv[0]); + } + } + + else { + if ( mesh->name == NULL ) { + mesh->name = argv[i]; + info->imprim = 5; + } + else if ( mesh->outf == NULL ) + mesh->outf = argv[i]; + else if ( mesh->move == NULL ) + mesh->move = argv[i]; + else { + fprintf(stdout," Argument %s ignored\n",argv[i]); + usage(argv[0]); + } + } + i++; + } + + /* check file names */ + if ( mesh->name == NULL || info->imprim == -99 ) { + fprintf(stdout,"\n -- PRINT (0 10(advised) -10) ?\n"); + fflush(stdin); + fscanf(stdin,"%d",&i); + info->imprim = i; + } + + if ( mesh->name == NULL ) { + mesh->name = (char *)calloc(128,sizeof(char)); + assert(mesh->name); + fprintf(stdout," -- FILE BASENAME ?\n"); + fflush(stdin); + fscanf(stdin,"%s",mesh->name); + } + if ( sol->name == NULL ) { + sol->name = (char *)calloc(128,sizeof(char)); + assert(sol->name); + strcpy(sol->name,mesh->name); + } + if ( mesh->outf == NULL ) { + mesh->outf = (char *)calloc(128,sizeof(char)); + assert(mesh->outf); + strcpy(mesh->outf,mesh->name); + ptr = strstr(mesh->outf,".mesh"); + if ( ptr ) *ptr = '\0'; + strcat(mesh->outf,".o.meshb"); + } + if ( abs(info->option) == 9 && mesh->move == NULL ) { + mesh->move = (char *)calloc(128,sizeof(char)); + assert(mesh->move); + fprintf(stdout," -- DISPLACEMENT FILE ?\n"); + fflush(stdin); + fscanf(stdin,"%s",mesh->move); + } + + return(1); +} + + +int parsop(pMesh mesh) { + int i,ret; + char *ptr,data[256]; + FILE *in; + + strcpy(data,mesh->name); + ptr = strstr(data,".mesh"); + if ( ptr ) *ptr = '\0'; + strcat(data,".mmg"); + in = fopen(data,"r"); + if ( !in ) { + sprintf(data,"%s","DEFAULT.mmg"); + in = fopen(data,"r"); + if ( !in ) return(1); + } + fprintf(stdout," %%%% %s OPENED\n",data); + + while ( !feof(in) ) { + ret = fscanf(in,"%s",data); + if ( !ret || feof(in) ) break; + for (i=0; i<strlen(data); i++) data[i] = tolower(data[i]); +/* + if ( !strcmp(data,"blayer") ) { + fscanf(in,"%d",&dummi); + if ( dummi ) { + mesh->blayer.nblay = dummi; + mesh->blayer.blay = (int*)calloc(dummi+1,sizeof(int)); + assert(mesh->blayer.blay); + mesh->blayer.blref = (int*)calloc(dummi+1,sizeof(int)); + assert(mesh->blayer.blref); + for (j=0; j<=dummi; j++) + fscanf(in,"%d %d",&mesh->blayer.blay[j],&mesh->blayer.blref[j]); + } + } +*/ + fprintf(stderr," ** UNKNOWN KEYWORD %s\n",data); + } + fclose(in); + + return(1); +} + + +void endcod() { + double ttot,ttim[TIMEMAX]; + int k,call[TIMEMAX]; + + TIM_chrono(OFF,&MMG_ctim[0]); + + for (k=0; k<TIMEMAX; k++) { + call[k] = MMG_ctim[k].call; + ttim[k] = MMG_ctim[k].call ? TIM_gttime(MMG_ctim[k]) : 0.0; + } + ttot = ttim[1]+ttim[2]+ttim[3]+ttim[4]; + ttim[0] = M_MAX(ttim[0],ttot); + + if ( abs(MMG_imprim) > 5 ) { + fprintf(stdout,"\n -- CPU REQUIREMENTS\n"); + fprintf(stdout," in/out %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[1]/ttim[0],call[1],ttim[1]/(float)call[1]); + fprintf(stdout," analysis %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[2]/ttim[0],call[2],ttim[2]/(float)call[2]); + fprintf(stdout," optim %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[3]/ttim[0],call[3],ttim[3]/(float)call[3]); + fprintf(stdout," total %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttot/ttim[0],call[0],ttot/(float)call[0]); + } + fprintf(stdout,"\n ELAPSED TIME %.2f SEC. (%.2f)\n",ttim[0],ttot); +} + + +/* set function pointers */ +int MMG_setfunc(int type) { + if ( type == 6 ) { + MMG_length = MMG_long_ani; + MMG_cavity = MMG_cavity_ani; + MMG_caltet = MMG_caltet_ani; //MMG_callong;//MMG_caltet_ani; + MMG_calte1 = MMG_calte1_ani; + MMG_caltet2 = MMG_caltet2_ani;//MMG_caltet2long_ani; + MMG_buckin = MMG_buckin_ani; + MMG_optlen = MMG_optlen_ani; + MMG_interp = MMG_interp_ani; + MMG_optlentet = MMG_optlentet_ani; + MMG_movevertex = MMG_movevertex_ani; + } + else if ( type == 1 ) { + MMG_length = MMG_long_iso; + MMG_cavity = MMG_cavity_iso; + MMG_caltet = MMG_caltet_iso; //MMG_callong; + MMG_calte1 = MMG_calte1_iso; + MMG_caltet2 = MMG_caltet2_iso; //MMG_caltet2long_iso;//MMG_caltet2_iso; + MMG_buckin = MMG_buckin_iso; + MMG_optlen = MMG_optlen_iso; + MMG_interp = MMG_interp_iso; + MMG_optlentet = MMG_optlentet_iso; + MMG_movevertex = MMG_movevertex_iso; + } + else if ( type != 3 ) { + fprintf(stdout," ** WRONG DATA TYPE\n"); + return(0); + } + return(1); +} + +/* /\* /\\* *\/ */ +/* /\* int main(int argc,char *argv[]) { *\/ */ +/* /\* pMesh mesh; *\/ */ +/* /\* pSol sol; *\/ */ +/* /\* Info *info; *\/ */ +/* /\* int alert; *\/ */ +/* /\* int k,iadr,i,jj,kk,ii; *\/ */ +/* /\* double lambda[3],v[3][3],*mold,*m; *\/ */ + +/* /\* fprintf(stdout," -- MMG3d, Release %s (%s) \n",M_VER,M_REL); *\/ */ +/* /\* fprintf(stdout," Copyright (c) LJLL/IMB, 2010\n"); *\/ */ +/* /\* fprintf(stdout," %s\n",COMPIL); *\/ */ + +/* /\* signal(SIGABRT,excfun); *\/ */ +/* /\* signal(SIGFPE,excfun); *\/ */ +/* /\* signal(SIGILL,excfun); *\/ */ +/* /\* signal(SIGSEGV,excfun); *\/ */ +/* /\* signal(SIGTERM,excfun); *\/ */ +/* /\* signal(SIGINT,excfun); *\/ */ +/* /\* atexit(endcod); *\/ */ + +/* /\* TIM_tminit(MMG_ctim,TIMEMAX); *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[0]); *\/ */ + +/* /\* mesh = (pMesh)M_calloc(1,sizeof(Mesh),"main"); *\/ */ +/* /\* assert(mesh); *\/ */ +/* /\* sol = (pSol)M_calloc(1,sizeof(Sol),"main"); *\/ */ +/* /\* assert(sol); *\/ */ +/* /\* sol->offset = 1; *\/ */ + + +/* /\* info = &mesh->info; *\/ */ + +/* /\* info->imprim = -99; *\/ */ +/* /\* info->memory = -1; *\/ */ +/* /\* info->ddebug = 0; *\/ */ +/* /\* info->rn2 = 3; *\/ */ +/* /\* info->rn = 500; *\/ */ +/* /\* info->option = 1; *\/ */ +/* /\* alert = 0; *\/ */ +/* /\* info->bucksiz = 0; *\/ */ +/* /\* info->noswap = 0; *\/ */ +/* /\* info->nomove = 0; *\/ */ +/* /\* info->noinsert = 0; *\/ */ +/* /\* info->dt = 1.; *\/ */ +/* /\* info->bdry = 0; *\/ */ + +/* /\* if ( !parsar(argc,argv,mesh,sol) ) return(1); *\/ */ +/* /\* MMG_imprim = info->imprim; *\/ */ + + +/* /\* if ( MMG_imprim ) fprintf(stdout,"\n -- INPUT DATA\n"); *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[1]); *\/ */ +/* /\* if ( !MMG_loadMesh(mesh,mesh->name) ) return(1); *\/ */ +/* /\* if ( !MMG_loadSol(sol,sol->name,mesh->npmax) ) return(1); *\/ */ +/* /\* if ( sol->np && sol->np != mesh->np ) { *\/ */ +/* /\* fprintf(stdout," ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n"); *\/ */ +/* /\* sol->np = 0; *\/ */ +/* /\* } *\/ */ + +/* /\* if ( !parsop(mesh) ) return(1); *\/ */ + +/* /\* if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np) ) return(0); *\/ */ + +/* /\* if ( !MMG_setfunc(sol->offset) ) return(1); *\/ */ +/* /\* if ( !MMG_scaleMesh(mesh,sol) ) return(1); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[1]); *\/ */ +/* /\* if ( MMG_imprim ) *\/ */ +/* /\* fprintf(stdout," -- DATA READING COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[1])); *\/ */ + +/* /\* if ( abs(MMG_imprim) > 3 ) { *\/ */ +/* /\* alert = MMG_outqua(mesh,sol); *\/ */ +/* /\* if(alert) { *\/ */ +/* /\* fprintf(stdout,"\n \n ## INVALID MESH. STOP\n"); *\/ */ +/* /\* exit(1); *\/ */ +/* /\* } *\/ */ +/* /\* if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); *\/ */ +/* /\* } *\/ */ + +/* /\* fprintf(stdout,"\n %s\n MODULE MMG3D-LJLL/IMB : %s (%s) %s\n %s\n", *\/ */ +/* /\* M_STR,M_VER,M_REL,sol->offset == 1 ? "ISO" : "ANISO",M_STR); *\/ */ +/* /\* fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8d\n",mesh->npmax); *\/ */ +/* /\* fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8d\n",mesh->ntmax); *\/ */ +/* /\* fprintf(stdout," MAXIMUM NUMBER OF ELEMENTS (NEMAX) : %8d\n",mesh->nemax); *\/ */ + + +/* /\* TIM_chrono(ON,&MMG_ctim[2]); *\/ */ +/* /\* if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 1 : ANALYSIS\n"); *\/ */ +/* /\* if ( !MMG_hashTetra(mesh) ) return(1); *\/ */ +/* /\* if ( !MMG_markBdry(mesh) ) return(1); *\/ */ +/* /\* if (abs(mesh->info.option)==10) { *\/ */ +/* /\* MMG_saveMesh(mesh,"tetra.mesh"); *\/ */ +/* /\* return(0); *\/ */ +/* /\* } *\/ */ + + +/* /\* if ( !sol->np && !MMG_doSol(mesh,sol) ) return(1); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[2]); *\/ */ +/* /\* if ( MMG_imprim ) *\/ */ +/* /\* fprintf(stdout," -- PHASE 1 COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[2])); *\/ */ + +/* /\* if ( info->ddebug ) MMG_chkmsh(mesh,1,1); *\/ */ + +/* /\* if ( abs(MMG_imprim) > 4 ) { *\/ */ +/* /\* MMG_prilen(mesh,sol); *\/ */ +/* /\* MMG_ratio(mesh,sol,NULL); *\/ */ +/* /\* } *\/ */ + +/* /\* #ifdef USE_SCOTCH *\/ */ +/* /\* /\\* renumbering begin *\\/ *\/ */ +/* /\* /\\*check enough vertex to renum*\\/ *\/ */ +/* /\* if ( (info->rn2 & 1) && (mesh->np/2. > info->rn)) { *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[5]); *\/ */ +/* /\* if ( MMG_imprim < -6) *\/ */ +/* /\* fprintf(stdout,"renumbering"); *\/ */ +/* /\* renumbering(info->rn, mesh, sol); *\/ */ + +/* /\* if ( !MMG_hashTetra(mesh) ) return(1); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[5]); *\/ */ +/* /\* if ( MMG_imprim < -6) *\/ */ +/* /\* fprintf(stdout," -- PHASE RENUMBERING COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[5])); *\/ */ +/* /\* if ( info->ddebug ) MMG_chkmsh(mesh,1,0); *\/ */ +/* /\* } *\/ */ +/* /\* /\\* renumbering end *\\/ *\/ */ +/* /\* #endif *\/ */ +/* /\* /\\* mesh optimization *\\/ *\/ */ +/* /\* if ( info->option ) { *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[3]); *\/ */ +/* /\* if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 2 : UNIT MESH\n"); *\/ */ +/* /\* if ( abs(info->option) == 9 ) { *\/ */ +/* /\* if(!MMG_mmg3d9(mesh,sol,&alert)) { *\/ */ +/* /\* if ( !MMG_unscaleMesh(mesh,sol) ) return(1); *\/ */ +/* /\* MMG_saveMesh(mesh,mesh->outf); *\/ */ +/* /\* MMG_saveSol(mesh,sol,mesh->outf); *\/ */ +/* /\* return(1); *\/ */ +/* /\* } *\/ */ +/* /\* /\\*puts("appel 1"); *\/ */ +/* /\* MMG_mmg3d1(mesh,sol,&alert);*\\/ *\/ */ +/* /\* for (k=1; k<=mesh->np; k++) { *\/ */ +/* /\* iadr = (k-1)*sol->offset + 1; *\/ */ +/* /\* m = &sol->met[iadr]; *\/ */ +/* /\* /\\*calcul du log de M*\\/ *\/ */ +/* /\* if ( !eigenv(1,m,lambda,v) ) { *\/ */ +/* /\* puts("pbs eigen"); *\/ */ +/* /\* return(0); *\/ */ +/* /\* } *\/ */ +/* /\* for (i=0; i<3; i++) lambda[i] = log(lambda[i]); *\/ */ +/* /\* mold = &sol->metold[iadr]; *\/ */ +/* /\* kk = 0; *\/ */ +/* /\* for (ii=0; ii<3; ii++) { *\/ */ +/* /\* for (jj=ii; jj<3; jj++) { *\/ */ +/* /\* mold[kk] = lambda[0]*v[0][ii]*v[0][jj] + *\/ */ +/* /\* lambda[1]*v[1][ii]*v[1][jj] + *\/ */ +/* /\* lambda[2]*v[2][ii]*v[2][jj]; *\/ */ +/* /\* kk = kk+1; *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ + +/* /\* if(!info->noinsert) { *\/ */ +/* /\* if(abs(info->option) == 4){ *\/ */ +/* /\* MMG_mmg3d4(mesh,sol,&alert); *\/ */ +/* /\* } else { *\/ */ +/* /\* MMG_mmg3d1(mesh,sol,&alert); *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ + +/* /\* TIM_chrono(OFF,&MMG_ctim[3]); *\/ */ +/* /\* if ( MMG_imprim ) *\/ */ +/* /\* fprintf(stdout," -- PHASE 2 COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[3])); *\/ */ +/* /\* } *\/ */ +/* /\* ///////////////////////////////////// *\/ */ +/* /\* /\\*MMG_caltet = MMG_caltetrao; *\/ */ +/* /\* for(k=1 ; k<=mesh->ne ; k++) { *\/ */ +/* /\* if(!mesh->tetra[k].v[0]) continue; *\/ */ +/* /\* mesh->tetra[k].qual = MMG_caltet(mesh,sol,k); *\/ */ +/* /\* } *\\/ *\/ */ +/* /\* ///////////////////////////////////// *\/ */ +/* /\* /\\* mesh regularisation *\\/ *\/ */ +/* /\* if ( info->option > -1 ) { *\/ */ +/* /\* #ifdef USE_SCOTCH *\/ */ +/* /\* /\\* renumbering begin *\\/ *\/ */ +/* /\* /\\*MMG_chkmsh(mesh,0,-1); *\/ */ +/* /\* puts("3er chk ok"); *\/ */ +/* /\* *\\/ *\/ */ +/* /\* if ( (info->rn2 & 2) && (mesh->np/2. > info->rn)) { *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[6]); *\/ */ +/* /\* if ( MMG_imprim < -6) *\/ */ +/* /\* fprintf(stdout,"renumbering"); *\/ */ +/* /\* renumbering(info->rn, mesh, sol); *\/ */ +/* /\* if ( !MMG_hashTetra(mesh) ) return(1); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[6]); *\/ */ +/* /\* if ( MMG_imprim < -6) *\/ */ +/* /\* fprintf(stdout," -- PHASE RENUMBERING COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[6])); *\/ */ +/* /\* if ( info->ddebug ) MMG_chkmsh(mesh,1,0); *\/ */ +/* /\* } *\/ */ +/* /\* /\\* renumbering end *\\/ *\/ */ +/* /\* #endif *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[4]); *\/ */ +/* /\* if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 3 : OPTIMIZATION\n"); *\/ */ +/* /\* if ( !alert ) { *\/ */ +/* /\* if ( info->option == 9 ) { *\/ */ +/* /\* MMG_optra4(mesh,sol); *\/ */ +/* /\* } else { *\/ */ +/* /\* MMG_optra4(mesh,sol); *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ + +/* /\* if ( info->ddebug ) MMG_chkmsh(mesh,1,1); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[4]); *\/ */ +/* /\* if ( MMG_imprim ) *\/ */ +/* /\* fprintf(stdout," -- PHASE 3 COMPLETED. %.2f sec.\n", *\/ */ +/* /\* TIM_gttime(MMG_ctim[4])); *\/ */ +/* /\* } *\/ */ +/* /\* ///////////////////////////////////// *\/ */ +/* /\* /\\*MMG_caltet = MMG_caltet_iso; *\/ */ +/* /\* for(k=1 ; k<=mesh->ne ; k++) { *\/ */ +/* /\* mesh->tetra[k].qual = MMG_caltet(mesh,sol,k); *\/ */ +/* /\* } *\\/ *\/ */ +/* /\* ///////////////////////////////////// *\/ */ + +/* /\* if ( info->option > -1 || abs(MMG_imprim) > 3 ) { *\/ */ +/* /\* MMG_outqua(mesh,sol); *\/ */ +/* /\* if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); *\/ */ +/* /\* MMG_prilen(mesh,sol); *\/ */ +/* /\* MMG_ratio(mesh,sol,NULL); *\/ */ +/* /\* } *\/ */ +/* /\* fprintf(stdout,"\n %s\n END OF MODULE MMG3D \n %s\n",M_STR,M_STR); *\/ */ +/* /\* if ( alert ) *\/ */ +/* /\* fprintf(stdout,"\n ## WARNING: INCOMPLETE MESH %d , %d\n", *\/ */ +/* /\* mesh->np,mesh->ne); *\/ */ + +/* /\* if ( MMG_imprim ) fprintf(stdout,"\n -- WRITING DATA FILE %s\n",mesh->outf); *\/ */ +/* /\* TIM_chrono(ON,&MMG_ctim[1]); *\/ */ +/* /\* if ( !MMG_unscaleMesh(mesh,sol) ) return(1); *\/ */ +/* /\* MMG_saveMesh(mesh,mesh->outf); *\/ */ +/* /\* if ( info->option == 9 ) { *\/ */ +/* /\* MMG_saveSol(mesh,sol,mesh->outf); *\/ */ +/* /\* MMG_saveVect(mesh,mesh->move); *\/ */ +/* /\* } *\/ */ +/* /\* else *\/ */ +/* /\* MMG_saveSol(mesh,sol,mesh->outf); *\/ */ +/* /\* TIM_chrono(OFF,&MMG_ctim[1]); *\/ */ +/* /\* if ( MMG_imprim ) fprintf(stdout," -- WRITING COMPLETED\n"); *\/ */ + +/* /\* /\\* free mem *\\/ *\/ */ +/* /\* M_free(mesh->point); *\/ */ +/* /\* M_free(mesh->tria); *\/ */ +/* /\* M_free(mesh->tetra); *\/ */ +/* /\* /\\*la desallocation de ce pointeur plante dans certains cas...*\\/ *\/ */ +/* /\* M_free(mesh->adja); *\/ */ +/* /\* M_free(mesh->disp->alpha); *\/ */ +/* /\* M_free(mesh->disp->mv); *\/ */ +/* /\* M_free(mesh->disp); *\/ */ + +/* /\* if ( sol->npfixe ) M_free(sol->met); *\/ */ +/* /\* M_free(sol); *\/ */ + +/* /\* if ( MMG_imprim < -4 || info->ddebug ) M_memDump(); *\/ */ +/* /\* M_free(mesh); *\/ */ +/* /\* return(0); *\/ */ +/* /\* } *\/ */ diff --git a/contrib/mmg3d/build/sources/mmg3d1.c b/contrib/mmg3d/build/sources/mmg3d1.c new file mode 100644 index 0000000000..a71424f863 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3d1.c @@ -0,0 +1,192 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +extern TIM_mytime MMG_ctim[TIMEMAX]; + +int MMG_npdtot,MMG_npuisstot,MMG_nvoltot,MMG_nprestot; +int MMG_npuiss,MMG_nvol,MMG_npres,MMG_npd; + +int MMG_cendellong(pMesh mesh,pSol sol,double declic,int base); + +int MMG_mmg3d1(pMesh mesh,pSol sol,int *alert) { + pBucket bucket; + int base,na,nd,nf,nna,nnd,dd,it,maxtou; + int naold,ndold; +//double q,declicw; +//pTetra pt; +//int nw; + + if ( abs(mesh->info.imprim) > 3 ) + fprintf(stdout," ** SIZE OPTIMIZATION\n"); + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + base = mesh->flag; + *alert = 0; + + nna = 0; + nnd = 0; + nf = 0; + it = 0; + maxtou = 100; +MMG_npdtot=0; +MMG_npuisstot=0; +MMG_nprestot=0; +MMG_nvoltot=0; + + /* 2. field points */ + if ( mesh->info.imprim < -4 ) { + MMG_prilen(mesh,sol); + fprintf(stdout," -- FIELD POINTS\n"); + } + /* create filter */ + bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ)); + if ( !bucket ) return(0); + + naold = ndold = 0; + do { + base = mesh->flag; + nf = 0; + + MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert); + nna += na; + nnd += nd; + + if ( *alert ) { + if ( nd < 1000 ) break; + else *alert = 0; + } + + /*test avec comme critere de qualite les longueurs*/ + /*if( it < 7 && !(it%3) ) { + ns = 0; + declic = 120.; //attention c'est 60*len + if ( !*alert && !mesh->info.noswap ) { + declicw = 180.; + nw += MMG_opttyp(mesh,sol,declicw,&alert); + ns = MMG_cendellong(mesh,sol,declic,-1); + if ( ns < 0 ) { + *alert = 1; + ns = -ns; + } + } + if ( mesh->info.imprim && ns ) + fprintf(stdout," %8d SWAPPED\n",ns); + //puts("on arrete la");exit(0); + } + + if( it > 5 ) { + + + //printf("on traite moins 1%% : %d %d %e\n",na,nd,(na+nd)/(double)mesh->np); + //printf("delold/ins %e %e\n",ndold / (double) (na+1),naold / (double) (nd+1)); + + if( it > 10 ) { + q = ndold / (double) (na+1); + if( q < 1.7 && q > 0.57) { + break; + } + q = naold / (double) (nd+1); + if( q < 1.7 && q > 0.57) { + break; + } + } + q = ndold / (double) (na+1); + if( q < 1.1 && q > 0.9) { + break; + } + q = naold / (double) (nd+1); + if( q < 1.1 && q > 0.9) { + break; + } + } + naold = na; + ndold = nd; + */ + + if ( it > 5 ) { + dd = abs(nd-na); + if ( dd < 5 || dd < 0.05*nd ) break; + else if ( it > 12 && nd >= na ) break; + } + if ( na + nd > 0 && abs(mesh->info.imprim) > 2 ) + fprintf(stdout," %8d INSERTED %8d REMOVED %8d FILTERED\n", + na,nd,nf); + } + while ( na+nd > 0 && ++it < maxtou ); + + + if ( nna+nnd && abs(mesh->info.imprim) < 3 ) { + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FILTERED\n",nna,nnd,nf); + } + +if(MMG_npdtot>0) { +fprintf(stdout," REJECTED : %5d\n",MMG_npdtot); +fprintf(stdout," VOL : %6.2f %% %5d \n", + 100*(MMG_nvoltot/(float) +MMG_npdtot),MMG_nvoltot); +fprintf(stdout," PUISS : %6.2f %% %5d \n", + 100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot); +fprintf(stdout," PROCHE : %6.2f %% %5d \n", + 100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot); +MMG_npdtot=0; +MMG_npuisstot=0; +MMG_nvoltot=0; +} + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + M_free(bucket->head); + M_free(bucket->link); + M_free(bucket); + + return(1); +} diff --git a/contrib/mmg3d/build/sources/mmg3d4.c b/contrib/mmg3d/build/sources/mmg3d4.c new file mode 100644 index 0000000000..67791e2f88 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3d4.c @@ -0,0 +1,237 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_npuiss,MMG_nvol,MMG_npres; +int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex; +int MMG_npuisstot,MMG_nvoltot,MMG_nprestot; +int MMG_npdtot; +int MMG_nplen,MMG_npref,MMG_bouffe; + +int ddebug; + +int MMG_mmg3d4(pMesh mesh,pSol sol,int *alert) { + Hedge hash; + pBucket bucket; + double declic; + int base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou; + double lmoy,LLLONG; + if ( abs(mesh->info.imprim) > 3 ) + fprintf(stdout," ** SIZE OPTIMIZATION\n"); + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + base = mesh->flag; + *alert = 0; + maxtou = 10; + nna = nns = nnd = 0; + it = 0; + declic = 3. / ALPHAD; + lmoy = 10.; + LLLONG = 1.5; + + nna = 10; + do { + na = nd = ns = 0; + if(0) ddebug = 1; + else ddebug = 0; + + if(!(it%2) ) { + bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ)); + if ( !bucket ) return(0); + + MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert); + if ( abs(mesh->info.imprim) > 5 ) + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FILTERED\n",na,nd,nf); + + M_free(bucket->head); + M_free(bucket->link); + M_free(bucket); + + } else { + ++mesh->flag; + } + //printf("IT %d $$$$$$$$$$$ LLLONG %9.3f\n",it,LLLONG); + nna = nns = nnd = 0; + + /*splitting*/ + if ( !mesh->info.noinsert && (!*alert) ) { + /* store points on edges */ + if ( !MMG_zaldy4(&hash,mesh->np) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM.\n"); + *alert = 2; + break; + } + + nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG); + if ( abs(mesh->info.imprim) > 5 ) { printf("lmoy %9.5f\n",lmoy); } + /*puts("--------------------------------------"); + puts("--------------------------------------"); + puts("--------------------------------------"); + */ + if ( *alert ) { + fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n"); + fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory); + MMG_saveMesh(mesh,"crash.meshb"); + MMG_saveSol(mesh,sol,"crash.solb"); + exit(0); + } + M_free(hash.item); + } + else if ( *alert ) nna = 0; + /* adjacencies */ + if ( nna /*|| it == (maxtou-1)*/ ) { + mesh->nt = 0; + if ( !MMG_hashTetra(mesh) ) return(0); + if ( !MMG_markBdry(mesh) ) return(0); + } + // printf("chkmsh\n"); + // MMG_saveMesh(mesh,"chk.mesh"); + //MMG_chkmsh(mesh,1,-1); + //if(it==1)exit(0); + /* delaunization */ + if ( !mesh->info.noswap && (nna || na) ) { + nns = MMG_cendel(mesh,sol,declic,base); + } + + /* deletion */ + /*if ( 0 && nna ) { + nnd = MMG_colvert(mesh,sol,base); + } */ + if ( nna+nnd+nns && abs(mesh->info.imprim) > 3 ) + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FLIPPED\n",nna+na,nnd+nd,nns); + + } + while ( na+nd+nns+nna+nnd > 0 && ++it < maxtou && lmoy > 1.3); + + if ( nna+nnd+nns && abs(mesh->info.imprim) < 4 ) { + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FLIPPED\n",nna,nnd,nns); + } + + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + //return(1); + //MMG_saveMesh(mesh,"aprescut.mesh"); + fprintf(stdout," ---\n"); + + /*analyze standard*/ + base = mesh->flag; + *alert = 0; + + nna = 0; + nnd = 0; + nf = 0; + it = 0; + maxtou = 100; + MMG_npdtot=0; + MMG_npuisstot=0; + MMG_nprestot=0; + MMG_nvoltot=0; + + /* 2. field points */ + if ( mesh->info.imprim < -4 ) { + MMG_prilen(mesh,sol); + fprintf(stdout," -- FIELD POINTS\n"); + } + + /* create filter */ + bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ)); + if ( !bucket ) return(0); + + do { + MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert); + nna += na; + nnd += nd; + if ( *alert ) { + if ( nd < 1000 ) break; + else *alert = 0; + } + if ( it > 5 ) { + dd = abs(nd-na); + if ( dd < 5 || dd < 0.05*nd ) break; + else if ( it > 12 && nd >= na ) break; + } + if ( na+nd && abs(mesh->info.imprim) > 3 ) + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FILTERED\n",na,nd,nf); + // MMG_saveMesh(mesh,"chk.mesh"); + // //if(it==1) exit(0); + } + while ( na+nd > 0 && ++it < maxtou ); + + if ( nna+nnd && abs(mesh->info.imprim) < 3 ) { + fprintf(stdout," %7d INSERTED %7d REMOVED %7d FILTERED\n",na,nd,nf); + } + + if(MMG_npdtot>0) { + fprintf(stdout," REJECTED : %5d\n",MMG_npdtot); + fprintf(stdout," VOL : %6.2f %% %5d \n", + 100*(MMG_nvoltot/(float) + MMG_npdtot),MMG_nvoltot); + fprintf(stdout," PUISS : %6.2f %% %5d \n", + 100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot); + fprintf(stdout," PROCHE : %6.2f %% %5d \n", + 100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot); + MMG_npdtot=0; + MMG_npuisstot=0; + MMG_nvoltot=0; + } + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + M_free(bucket->head); + M_free(bucket->link); + M_free(bucket); + + + return(1); +} diff --git a/contrib/mmg3d/build/sources/mmg3d9.c b/contrib/mmg3d/build/sources/mmg3d9.c new file mode 100644 index 0000000000..e691727bf5 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3d9.c @@ -0,0 +1,528 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex; + +/*essaie d'enlever les tets ayant plus d'une face de peau pour faciliter le bouger*/ +int MMG_optfacespeau(pMesh mesh,pSol sol) { + double declic; + pTetra pt; + pQueue queue; + int it,maxtou,i,iadr,*adja,npeau,nwtot,nw,k; + + declic = 1.7 / ALPHAD; + maxtou = 10; + it = 0; + + do { + queue = MMG_kiuini(mesh,mesh->nemax,declic,-1); + assert(queue); + nw = 0; + nwtot = 0; + do { + k = MMG_kiupop(queue); + pt = &mesh->tetra[k]; + if ( !k ) break; + if ( !pt->v[0] ) continue; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + /*optim bdry tetra*/ + npeau = 0; + for(i=0 ; i<4 ; i++) { + if(!adja[i])npeau++; + } + if(npeau>1 ) { + nwtot++; + //if(mesh->info.imprim<0) printf("%d faces de peau!!!! %d %e\n",npeau,k,mesh->tetra[k].qual * ALPHAD); + nw += MMG_opt2peau(mesh,sol,queue,k,declic); + continue; + } + } + while (k); + fprintf(stdout," %7d / %7d BDRY TETS\n",nw,nwtot); + MMG_kiufree(queue); + } + while ( nw && ++it < maxtou ); + + return(1); +} + +/*collapse*/ +int MMG_colps(pMesh mesh,pSol sol,int *nd) { + pTetra pt,pt1; + pPoint pa,pb; + double len,*ca,*cb,*ma,*mb; + float coef; + int i,k,l,jel,num,lon,ndd,npp,ia,ib,ipa,ipb,nedep,base; + int *adja,adj,iadr; + List list; + char tabar; + +MMG_nlen = 0; +MMG_ncal = 0; +MMG_ntopo = 0; +MMG_nex = 0; + + npp = 0; + ndd = 0; + coef = QDEGRAD; + nedep = mesh->ne; + base = ++mesh->flag; + /*Try collapse*/ + for (k=1; k<=nedep; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag != base-1 ) continue; + + /* mark internal edges */ + tabar = 0; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + if ( !adj || pt->ref != mesh->tetra[adj].ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + } + if ( tabar == ALL_BDRY ) continue; + + /* internal edge */ + for (i=0; i<6; i++) { + if ( tabar & 1<<i ) continue; + else if ( pt->edge & 1 << i ) continue; + + /* edge length */ + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + ca = &pa->c[0]; + cb = &pb->c[0]; + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + /* coquille */ + lon = MMG_coquil(mesh,k,i,&list); + for (l=1; l<=lon; l++) { + jel = list.tetra[l] / 6; + num = list.tetra[l] % 6; + pt1 = &mesh->tetra[jel]; + pt1->edge |= 1 << num; + } + if ( lon < 3 ) continue; + len = MMG_length(ca,cb,ma,mb); + + if ( len < LSHORT ) { + npp++; + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( MMG_colpoi(mesh,sol,k,ia,ib,coef) ) { + MMG_delPt(mesh,ipb); + ndd++; + break; + } + else if ( MMG_colpoi(mesh,sol,k,ib,ia,coef) ) { + MMG_delPt(mesh,ipa); + ndd++; + break; + } + } + } + } + + *nd = ndd; +printf("analyzed %d \n",npp); +printf("rejected colpoi : cal %d , len %d , topo %d , ex %d\n",MMG_ncal,MMG_nlen,MMG_ntopo,MMG_nex); + + if ( *nd > 0 && abs(mesh->info.imprim) > 2 ) + fprintf(stdout," %8d REMOVED \n",*nd); + + return(1); + +} + + +/* dichotomy: check if nodes can move */ +int MMG_dikomv(pMesh mesh,pSol sol,short t) { + pTetra pt; + pPoint ppt; + pDispl pd; + double vol,c[4][3]; + double alpha,coor[3]; + int k,i,nm; +/*double hmax,*mp,h1,lambda[3],dd; +int iadr; +Info *info; +*/ + pd = mesh->disp; + + alpha = (double)t / SHORT_MAX; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt->v[i] ]; + ppt->tmp = k; + if ( ppt->tag & M_MOVE ) { + c[i][0] = ppt->c[0] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 0]; + c[i][1] = ppt->c[1] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 1]; + c[i][2] = ppt->c[2] + alpha * pd->mv[3*(pt->v[i]-1) + 1 + 2]; + } + else + memcpy(c[i],ppt->c,3*sizeof(double)); + } + + vol = MMG_quickvol(c[0],c[1],c[2],c[3]); + if ( vol < 1e-24/*EPS2*/ ) { + if(mesh->info.imprim < 0) printf("vol reject %d %e %e\n",k,vol,pt->qual * ALPHAD); + return(0); + } + } + /* update metrics */ + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if(ppt->tag & M_UNUSED) continue; +//#warning a mettre ou pas? + if(ppt->tag & M_BDRY) continue; + if ( ppt->tag & M_MOVE ) { + coor[0] = ppt->c[0] + alpha * pd->mv[3*(k-1) + 1 + 0]; + coor[1] = ppt->c[1] + alpha * pd->mv[3*(k-1) + 1 + 1]; + coor[2] = ppt->c[2] + alpha * pd->mv[3*(k-1) + 1 + 2]; +if(MMG_computeMetric(mesh,sol,k,coor) == -1) ;//printf("point %d not found\n",k); +// /*pour mettre une metrique analytique*/ +// iadr = (k-1)*sol->offset + 1; +// mp = &sol->met[iadr]; +// +// info = &mesh->info; +// +// /* normalize metrics */ +// dd = (double)PRECI / info->delta; +// +// hmax = 0.5; +// h1 = hmax * fabs(1-exp(-fabs((coor[2] * 1./dd + info->min[2])+4))) + 0.008; +// lambda[2]=1./(h1*h1); +// lambda[1]=1./(hmax*hmax); +// lambda[0]=1./(hmax*hmax); +// dd = 1.0 / (dd*dd); +// +// mp[0]=dd*lambda[0]; +// mp[1]=0; +// mp[3]=dd*lambda[1]; +// mp[2]=0; +// mp[4]=0; +// mp[5]=dd*lambda[2]; +// /*fin metrique analytique*/ + } + } + + /* update point coords */ + nm = 0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_MOVE ) { + ppt->c[0] += alpha * pd->mv[3*(k-1) + 1 + 0]; + ppt->c[1] += alpha * pd->mv[3*(k-1) + 1 + 1]; + ppt->c[2] += alpha * pd->mv[3*(k-1) + 1 + 2]; + pd->alpha[k] = t; + if ( t == SHORT_MAX ) ppt->tag &= ~M_MOVE; + nm++; + } + } + + if ( mesh->info.imprim < 0 ) fprintf(stdout," %7d NODES UPDATED\n",nm); + return(nm); +} + + +/* check if displacement ok */ +int MMG_chkmov(pMesh mesh,char level) { + pTetra pt; + pPoint ppt; + pDispl pd; + double vol; + int k,nc; + + pd = mesh->disp; + + nc = 0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_MOVE ) { + if ( pd->alpha[k] < SHORT_MAX ) return(0); + ppt->tag &= ~M_MOVE; + nc++; + } + } + + /* check element validity */ + if ( level > 0 ) { + for (k=1 ; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + vol = MMG_voltet(mesh,k); + if ( vol < 0.0 ) return(0); + } + } + + return(1); +} + +int MMG_optra9(pMesh mesh,pSol sol) { + double declicw; + double declic; + int base,nm,ns,it,maxtou,alert,nw,k; + + /* optim coquil */ + alert = 0; + maxtou = 10; + it = 0; + + for (k=1; k<=mesh->ne; k++) mesh->tetra[k].flag = mesh->flag; + for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag; + + declicw = 5./ALPHAD; + declic = 1.1 / ALPHAD;//1.1 pour mmg3d + + do { + for (k=1; k<=mesh->ne; k++) mesh->tetra[k].flag = mesh->flag; + for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag; + base = ++mesh->flag; + + ns = 0; + if ( !alert && !mesh->info.noswap ) { + ns = MMG_cendel(mesh,sol,declic,base); + if ( ns < 0 ) { + alert = 1; + ns = -ns; + } + } + nw = 0; + /*if (!mesh->info.noinsert) nw = MMG_pretreat(mesh,sol,declicw,&alert); + */ + /*sur des surfaces courbes, il existe des tetras ayant 4 points de peau avec Q=3*/ + if (1/*!mesh->info.noswap*/ /*&& (it < 10)*/ ) { + nw += MMG_opttyp(mesh,sol,declicw,&alert); + } + + nm = MMG_optlen(mesh,sol,declic,base); +// if(abs(mesh->info.option)!=9 || !mesh->disp) if(it<2) MMG_optlap(mesh,sol); + + if ( mesh->info.imprim && nw+ns+nm ) + fprintf(stdout," %8d IMPROVED %8d SWAPPED %8d MOVED\n",nw,ns,nm); + } + while ( ns+nm/*(ns && (ns > 0.005*mesh->ne || it < 5))*/ && ++it < maxtou ); + + return(1); +} + + +int MMG_mmg3d9(pMesh mesh,pSol sol,int *alert) { + pPoint ppt; + pTetra pt; + double declic; + double *m,*mold,qworst; + int k,nm,iter,maxiter; + int base,nnd,nns,sit,maxtou,ns,iadr,iold; + short t,i,it,alpha; + + if ( abs(mesh->info.imprim) > 3 ) + fprintf(stdout," ** MOVING MESH\n"); + + /*alloc et init metold*/ + sol->metold = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_mmg3d9"); + assert(sol->metold); + mesh->disp->cold = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_mmg3d9"); + assert(mesh->disp->cold); + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + mesh->disp->cold[3*(k-1) + 1 + 0] = ppt->c[0]; + mesh->disp->cold[3*(k-1) + 1 + 1] = ppt->c[1]; + mesh->disp->cold[3*(k-1) + 1 + 2] = ppt->c[2]; + } + + switch (sol->offset) { + case 1: + for (k=1; k<=sol->np; k++) { + sol->metold[k] = sol->met[k]; + } + break; + + case 6: + for (k=1; k<=mesh->np; k++) { + iadr = (k-1)*sol->offset + 1; + m = &sol->met[iadr]; + mold = &sol->metold[iadr]; + for (i=0; i<sol->offset; i++) mold[i] = m[i]; + } + break; + default: + fprintf(stderr," ## SPECIFIC DATA NOT USED.\n"); + exit(2); + } + + + /* move grid nodes */ + t = SHORT_MAX; + alpha = 0; + iter = 0; + maxiter = 200; + declic = 1.1/ALPHAD; + iold = 1; + + /* move grid nodes */ + t = SHORT_MAX; + if ( MMG_dikomv(mesh,sol,t) ) { + if ( mesh->info.imprim ) fprintf(stdout," %7d NODES MOVED\n",mesh->np); + } + else { + fprintf(stdout," TRYING DICHO\n"); + while (alpha < SHORT_MAX && iter < maxiter) { + t = SHORT_MAX - alpha; + i = 0; + do { + nm = MMG_dikomv(mesh,sol,t); + if ( nm ) { + alpha += t; + break; + } + t = t >> 1; + } while (i++ < 10); + + /*si pas de mouvement 2 iter de suite stop*/ + if ( (i==11) && (iold==11)) { + fprintf(stdout," NO MOVEMENT ## UNCOMPLETE DISPLACEMENT\n"); + return(0); + } + iold = i; + /* update quality */ + qworst = 0.; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + pt->qual = MMG_caltet(mesh,sol,k); + qworst = M_MAX(qworst,pt->qual); + } + + + if ( mesh->info.imprim && nm ) + fprintf(stdout," %7d NODES MOVED\n",nm); + + printf("%%%% ITER %d alpha (%d) %d < %d\n",iter,i,alpha,SHORT_MAX); + + if ( i>1 ) { + fprintf(stdout," CAN'T MOVED\n"); + if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol); + nnd = 0; + nns = 0; + sit = 0; + maxtou = 10; + do { + it = 0; + base = mesh->flag; + ns = 0;//MMG_cendel(mesh,sol,declic,base); + if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol); + if ( ns < 0 ) { + *alert = 1; + ns = -ns; + } + nns += ns; + if ( ns && abs(mesh->info.imprim) > 4 ) + fprintf(stdout," %7d SWAPPED\n",ns); + } + while ( ns && ++sit < maxtou ); + + if ( nnd+nns && abs(mesh->info.imprim) < 3 ) { + fprintf(stdout," %7d REMOVED %7d SWAPPED\n",nnd,nns); + } + } + + if ( qworst < 10./ALPHAD ) { + MMG_optra4(mesh,sol); + } else { + MMG_optra9(mesh,sol); + } + if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol); + MMG_outqua(mesh,sol); + iter++; + + } + + /* check mesh */ + if ( iter==maxiter && !MMG_chkmov(mesh,1) ) { + fprintf(stdout," ## UNCOMPLETE DISPLACEMENT\n"); + return(0); + } + } + + if(!mesh->info.noswap) MMG_optfacespeau(mesh,sol); + + /* update quality */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( pt->v[0] ) + pt->qual = MMG_caltet(mesh,sol,k); + } + + if ( mesh->info.imprim < 0 ) { + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + } + + // M_free(sol->metold); +/* M_free(mesh->disp); + mesh->disp = 0; + */return(1); +} + diff --git a/contrib/mmg3d/build/sources/mmg3dConfig.h b/contrib/mmg3d/build/sources/mmg3dConfig.h new file mode 100644 index 0000000000..6fc584d764 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3dConfig.h @@ -0,0 +1,50 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +// the configured options and settings for Tutorial +#define Tutorial_VERSION_MAJOR +#define Tutorial_VERSION_MINOR + + diff --git a/contrib/mmg3d/build/sources/mmg3dlib.c b/contrib/mmg3d/build/sources/mmg3dlib.c new file mode 100644 index 0000000000..b03e3c0ff5 --- /dev/null +++ b/contrib/mmg3d/build/sources/mmg3dlib.c @@ -0,0 +1,494 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* +mmg3dlib(int option, ): to use mmg3d via a library + +option = + fprintf(stdout," 1 adaptation\n"); + fprintf(stdout," 9 moving mesh\n"); + fprintf(stdout," -n turn off optimisation\n"); + +*/ +#include "compil.date" +#include "mesh.h" +#include "eigenv.h" + +TIM_mytime MMG_ctim[TIMEMAX]; +short MMG_imprim; + +static void MMG_excfun(int sigid) { + switch (sigid) { + case SIGFPE: + fprintf(stderr," ## FP EXCEPTION. STOP\n"); + break; + case SIGILL: + fprintf(stderr," ## ILLEGAL INSTRUCTION. STOP\n"); + break; + case SIGSEGV: + fprintf(stderr," ## SEGMENTATION FAULT. STOP\n"); + break; + case SIGABRT: + case SIGTERM: + case SIGINT: + fprintf(stderr," ## ABNORMAL END. STOP\n"); + break; + } + exit(1); +} + +void MMG_endcod() { + double ttot,ttim[TIMEMAX]; + int k,call[TIMEMAX]; + + TIM_chrono(OFF,&MMG_ctim[0]); + + for (k=0; k<TIMEMAX; k++) { + call[k] = MMG_ctim[k].call; + ttim[k] = MMG_ctim[k].call ? TIM_gttime(MMG_ctim[k]) : 0.0; + } + ttot = ttim[1]+ttim[2]+ttim[3]+ttim[4]; + ttim[0] = M_MAX(ttim[0],ttot); + + if ( abs(MMG_imprim) > 5 ) { + fprintf(stdout,"\n -- CPU REQUIREMENTS\n"); + fprintf(stdout," in/out %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[1]/ttim[0],call[1],ttim[1]/(float)call[1]); + fprintf(stdout," analysis %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[2]/ttim[0],call[2],ttim[2]/(float)call[2]); + fprintf(stdout," optim %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttim[3]/ttim[0],call[3],ttim[3]/(float)call[3]); + fprintf(stdout," total %8.2f %% %3d. calls, %7.2f sec/call\n", + 100.*ttot/ttim[0],call[0],ttot/(float)call[0]); + } + fprintf(stdout,"\n ELAPSED TIME %.2f SEC. (%.2f)\n",ttim[0],ttot); +} + + +int MMG_inputdata(pMesh mesh,pSol sol) { + pPoint ppt; + int k; + + + mesh->npfixe = mesh->np; + mesh->ntfixe = mesh->nt; + mesh->nefixe = mesh->ne; + + /* keep track of empty links */ + mesh->npnil = mesh->np + 1; + mesh->nenil = mesh->ne + 1; + for (k=mesh->npnil; k<mesh->npmax-1; k++) + mesh->point[k].tmp = k+1; + for (k=mesh->nenil; k<mesh->nemax-1; k++) + mesh->tetra[k].v[3] = k+1; + if ( mesh->nt ) { + mesh->ntnil = mesh->nt + 1; + for (k=mesh->ntnil; k<mesh->ntmax-1; k++) + mesh->tria[k].v[2] = k+1; + } + /*tag points*/ + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + ppt->tag = M_UNUSED; + } + return(1); +} + +int MMG_tassage(pMesh mesh,pSol sol) { + pTetra pt,ptnew; + pTria pt1; + pPoint ppt,pptnew; + int np,k,ne,nbl,isol,isolnew,i; + + /*rebuild triangles*/ + MMG_markBdry(mesh); + + /* compact vertices */ + np=0; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ppt->tmp = ++np; + } + + + /* compact triangles */ + for (k=1; k<=mesh->nt; k++) { + pt1 = &mesh->tria[k]; + pt1->v[0] = mesh->point[pt1->v[0]].tmp; + pt1->v[1] = mesh->point[pt1->v[1]].tmp; + pt1->v[2] = mesh->point[pt1->v[2]].tmp; + } + + /* compact tetrahedra */ + ne = 0; + nbl = 1; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) { + continue; + } + for(i=0 ; i<4 ; i++) + pt->bdryref[i] = -1; + pt->v[0] = mesh->point[pt->v[0]].tmp; + pt->v[1] = mesh->point[pt->v[1]].tmp; + pt->v[2] = mesh->point[pt->v[2]].tmp; + pt->v[3] = mesh->point[pt->v[3]].tmp; + ne++; + // if(k!=nbl) { + // printf("on voudrait tasser\n"); + // ptnew = &mesh->tetra[nbl]; + // memcpy(ptnew,pt,sizeof(Tetra)); + // nbl++; + // } + // + // for(i=0 ; i<4 ; i++) + // ptnew->bdryref[i] = 0; + // if(k != nbl) { + // memset(pt,0,sizeof(Tetra)); + // pt->qual = 0.0; + // pt->edge = 0; + // } + // nbl++; + } + // mesh->ne = ne; + + /* compact metric */ + nbl = 1; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + isol = (k-1) * sol->offset + 1; + isolnew = (nbl-1) * sol->offset + 1; + + for (i=0; i<sol->offset; i++) + sol->met[isolnew + i] = sol->met[isol + i]; + ++nbl; + } + + + /*compact vertices*/ + np = 0; + nbl = 1; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + pptnew = &mesh->point[nbl]; + memcpy(pptnew,ppt,sizeof(Point)); + ppt->tag &= ~M_UNUSED; + assert(ppt->tmp == nbl); + np++; + if(k != nbl) { + ppt = &mesh->point[k]; + memset(ppt,0,sizeof(Point)); + ppt->tag = M_UNUSED; + } + nbl++; + } + mesh->np = np; + sol->np = np; + + for(k=1 ; k<=mesh->np ; k++) + mesh->point[k].tmp = 0; + + mesh->npnil = mesh->np + 1; + for (k=mesh->npnil; k<mesh->npmax-1; k++) + mesh->point[k].tmp = k+1; + + mesh->nenil = mesh->ne + 1; + for (k=mesh->nenil; k<mesh->nemax-1; k++) + mesh->tetra[k].v[3] = k+1; + + mesh->ntnil = mesh->nt + 1; + for (k=mesh->ntnil; k<mesh->ntmax-1; k++) + mesh->tria[k].v[2] = k+1; + + + + return(1); +} + +int MMG_mmg3dlib(int opt[9],MMG_pMesh mesh,MMG_pSol sol) { + int alert; + Info *info; + short imprim; + int k,iadr,i,jj,kk,ii,im; + double lambda[3],v[3][3],*mold,*m; + fprintf(stdout," -- MMG3d, Release %s (%s) \n",M_VER,M_REL); + fprintf(stdout," Copyright (c) LJLL/IMB, 2010\n"); + fprintf(stdout," %s\n",COMPIL); + + + signal(SIGABRT,MMG_excfun); + signal(SIGFPE,MMG_excfun); + signal(SIGILL,MMG_excfun); + signal(SIGSEGV,MMG_excfun); + signal(SIGTERM,MMG_excfun); + signal(SIGINT,MMG_excfun); + /* atexit(MMG_endcod); +*/ + + TIM_tminit(MMG_ctim,TIMEMAX); + TIM_chrono(ON,&MMG_ctim[0]); + TIM_chrono(OFF,&MMG_ctim[0]); + /* default values */ + info = &mesh->info; + + info->imprim = opt[6]; + info->memory = 0; + info->ddebug = opt[1]; + info->option = opt[0]; + info->bucksiz = opt[2]; + info->noswap = opt[3]; + info->nomove = opt[5]; + info->noinsert = opt[4]; + info->rn2 = opt[7];//3; + info->rn = opt[8];//500; + alert = 0; + info->dt = 1.; + info->bdry = 0; + + imprim = info->imprim; + MMG_imprim = imprim; + + if ( imprim ) fprintf(stdout,"\n -- INPUT DATA\n"); + TIM_chrono(ON,&MMG_ctim[1]); + MMG_inputdata(mesh,sol); + if ( sol->np && sol->np != mesh->np ) { + fprintf(stdout," ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n"); + sol->np = 0; + } + /*read displacement*/ + if ( abs(info->option) == 9 && !mesh->disp) { + //M_free(mesh->adja); + fprintf(stdout," ## WARNING: NO DISPLACEMENT. IGNORED\n"); + return(0); + } + if ( !MMG_setfunc(sol->offset) ) return(1); + if ( !MMG_scaleMesh(mesh,sol) ) return(1); + TIM_chrono(OFF,&MMG_ctim[1]); + if ( imprim ) + fprintf(stdout," -- DATA READING COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[1])); + + alert = MMG_outqua(mesh,sol); + if(alert) { + fprintf(stdout,"\n \n ## INVALID MESH. STOP\n"); + exit(1); + } + if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); + + fprintf(stdout,"\n %s\n MODULE MMG3D-LJLL/IMB : %s (%s) %s\n %s\n", + M_STR,M_VER,M_REL,sol->offset == 1 ? "ISO" : "ANISO",M_STR); + fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8d\n",mesh->npmax); + fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8d\n",mesh->ntmax); + fprintf(stdout," MAXIMUM NUMBER OF ELEMENTS (NEMAX) : %8d\n",mesh->nemax); + + /* mesh analysis */ + TIM_chrono(ON,&MMG_ctim[2]); + if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 1 : ANALYSIS\n"); + if ( !MMG_hashTetra(mesh) ) return(1); + if ( !MMG_markBdry(mesh) ) return(1); + if (abs(mesh->info.option)==10) { + MMG_saveMesh(mesh,"tetra.mesh"); + return(0); + } + if ( !sol->np) { + fprintf(stdout," WARNING NO METRIC FOUND %d\n",sol->np); + im = 1; + if(!MMG_doSol(mesh,sol) ) return(1); + } else + im = 0; + + TIM_chrono(OFF,&MMG_ctim[2]); + if ( MMG_imprim ) + fprintf(stdout," -- PHASE 1 COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[2])); + if ( info->ddebug ) MMG_chkmsh(mesh,1,1); + + if ( abs(MMG_imprim) > 4 ) { + MMG_prilen(mesh,sol); + MMG_ratio(mesh,sol,NULL); + } + +#ifdef USE_SCOTCH + /* renumbering begin */ + if ( info->rn2 & 1 ) { + TIM_chrono(ON,&MMG_ctim[5]); + if ( MMG_imprim < -6) + fprintf(stdout,"renumbering"); + renumbering(info->rn, mesh, sol); + + if ( !MMG_hashTetra(mesh) ) return(1); + TIM_chrono(OFF,&MMG_ctim[5]); + if ( MMG_imprim < -6) + fprintf(stdout," -- PHASE RENUMBERING COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[5])); + if ( info->ddebug ) MMG_chkmsh(mesh,1,0); + } + /* renumbering end */ +#endif + + /* mesh optimization */ + if ( info->option ) { + TIM_chrono(ON,&MMG_ctim[3]); + if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 2 : UNIT MESH\n"); + if ( abs(info->option) == 9 ) { + if(!MMG_mmg3d9(mesh,sol,&alert)) { + if ( !MMG_unscaleMesh(mesh,sol) ) return(1); + MMG_saveMesh(mesh,"errormoving.mesh"); + //MMG_saveSol(mesh,sol,mesh->outf); + return(1); + } + /*puts("appel 1"); + MMG_mmg3d1(mesh,sol,&alert);*/ + for (k=1; k<=mesh->np; k++) { + iadr = (k-1)*sol->offset + 1; + m = &sol->met[iadr]; + /*calcul du log de M*/ + if ( !eigenv(1,m,lambda,v) ) { + puts("pbs eigen"); + return(0); + } + for (i=0; i<3; i++) lambda[i] = log(lambda[i]); + mold = &sol->metold[iadr]; + kk = 0; + for (ii=0; ii<3; ii++) { + for (jj=ii; jj<3; jj++) { + mold[kk] = lambda[0]*v[0][ii]*v[0][jj] + + lambda[1]*v[1][ii]*v[1][jj] + + lambda[2]*v[2][ii]*v[2][jj]; + kk = kk+1; + } + } + } + } + + if(!info->noinsert) { + if(abs(info->option) == 4){ + MMG_mmg3d4(mesh,sol,&alert); + } else { + MMG_mmg3d1(mesh,sol,&alert); + } + } + + TIM_chrono(OFF,&MMG_ctim[3]); + if ( MMG_imprim ) + fprintf(stdout," -- PHASE 2 COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[3])); + } + + /* mesh regularisation */ + if ( info->option > -1 ) { +#ifdef USE_SCOTCH + /* renumbering begin */ + /*MMG_chkmsh(mesh,0,-1); + puts("3er chk ok"); + */ + if ( info->rn2 & 2 ) { + TIM_chrono(ON,&MMG_ctim[6]); + if ( MMG_imprim < -6) + fprintf(stdout,"renumbering"); + renumbering(info->rn, mesh, sol); + if ( !MMG_hashTetra(mesh) ) return(1); + TIM_chrono(OFF,&MMG_ctim[6]); + if ( MMG_imprim < -6) + fprintf(stdout," -- PHASE RENUMBERING COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[6])); + if ( info->ddebug ) MMG_chkmsh(mesh,1,0); + } + /* renumbering end */ +#endif + TIM_chrono(ON,&MMG_ctim[4]); + if ( MMG_imprim ) fprintf(stdout,"\n -- PHASE 3 : OPTIMIZATION\n"); + if ( !alert ) { + if ( info->option == 9 ) { + MMG_optra4(mesh,sol); + } else { + MMG_optra4(mesh,sol); + } + } + + if ( info->ddebug ) MMG_chkmsh(mesh,1,1); + TIM_chrono(OFF,&MMG_ctim[4]); + if ( MMG_imprim ) + fprintf(stdout," -- PHASE 3 COMPLETED. %.2f sec.\n", + TIM_gttime(MMG_ctim[4])); + } + + + if ( info->option > -1 || abs(MMG_imprim) > 3 ) { + MMG_outqua(mesh,sol); + if(MMG_imprim < 0) MMG_outquacubic(mesh,sol); + MMG_prilen(mesh,sol); + MMG_ratio(mesh,sol,NULL); + } + fprintf(stdout,"\n %s\n END OF MODULE MMG3D \n %s\n",M_STR,M_STR); + if ( alert ) + fprintf(stdout,"\n ## WARNING: INCOMPLETE MESH %d , %d\n", + mesh->np,mesh->ne); + + if ( MMG_imprim ) fprintf(stdout,"\n -- SAVING DATA FILE \n"); + TIM_chrono(ON,&MMG_ctim[1]); + if ( !MMG_unscaleMesh(mesh,sol) ) return(1); + MMG_tassage(mesh,sol); + + TIM_chrono(OFF,&MMG_ctim[1]); + if ( MMG_imprim ) { + fprintf(stdout," NUMBER OF GIVEN VERTICES %8d\n",mesh->npfixe); + if ( mesh->ntfixe ) + fprintf(stdout," NUMBER OF GIVEN TRIANGLES %8d\n",mesh->ntfixe); + fprintf(stdout," NUMBER OF GIVEN ELEMENTS %8d\n",mesh->nefixe); + fprintf(stdout," TOTAL NUMBER OF VERTICES %8d\n",mesh->np); + fprintf(stdout," TOTAL NUMBER OF TRIANGLES %8d\n",mesh->nt); + fprintf(stdout," TOTAL NUMBER OF ELEMENTS %8d\n",mesh->ne); + } + + if ( MMG_imprim ) fprintf(stdout," -- SAVING COMPLETED\n"); + + if ( MMG_imprim < -4 || info->ddebug ) M_memDump(); + + return(alert); +} diff --git a/contrib/mmg3d/build/sources/movevertex.c b/contrib/mmg3d/build/sources/movevertex.c new file mode 100644 index 0000000000..207afc28f4 --- /dev/null +++ b/contrib/mmg3d/build/sources/movevertex.c @@ -0,0 +1,366 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_movevertex_ani(pMesh mesh,pSol sol,int k,int ib) { + pTetra pt,pt1; + pPoint ppa,ppb,p1,p2,p3; + List list; + int j,iadr,ipb,iter,maxiter,l,lon,iel,i1,i2,i3; + double *mp,coe; + double ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3]; + assert(k); + assert(ib<4); + pt = &mesh->tetra[k]; + ppa = &mesh->point[pt->v[ib]]; + iadr = (pt->v[ib]-1)*sol->offset + 1; + mp = &sol->met[iadr]; + + /*compute normal*/ + i1 = pt->v[MMG_idir[ib][0]]; + i2 = pt->v[MMG_idir[ib][1]]; + i3 = pt->v[MMG_idir[ib][2]]; + p1 = &mesh->point[i1]; + p2 = &mesh->point[i2]; + p3 = &mesh->point[i3]; + + ax = p3->c[0] - p1->c[0]; + ay = p3->c[1] - p1->c[1]; + az = p3->c[2] - p1->c[2]; + + bx = p2->c[0] - p1->c[0]; + by = p2->c[1] - p1->c[1]; + bz = p2->c[2] - p1->c[2]; + + nx = (ay*bz - az*by); + ny = (az*bx - ax*bz); + nz = (ax*by - ay*bx); + + dd = sqrt(nx*nx+ny*ny+nz*nz); + dd = 1./dd; + nx *=dd; + ny *=dd; + nz *=dd; + len = 0; + for (j=0; j<3; j++) { + ipb = pt->v[ MMG_idir[ib][j] ]; + ppb = &mesh->point[ipb]; + + ax = ppb->c[0] - ppa->c[0]; + ay = ppb->c[1] - ppa->c[1]; + az = ppb->c[2] - ppa->c[2]; + + dd = mp[0]*ax*ax + mp[3]*ay*ay + mp[5]*az*az \ + + 2.0*(mp[1]*ax*ay + mp[2]*ax*az + mp[4]*ay*az); + assert(dd>0); + len += sqrt(dd); + } + + dd = 1.0 / (double)3.; + len = 1.0 / len; + len *= dd; + memcpy(oldc,ppa->c,3*sizeof(double)); + + lon = MMG_boulep(mesh,k,ib,&list); + if(mesh->info.imprim < 0 ) if(lon < 4 && lon) printf("lon petit : %d\n",lon); + if(!lon) return(0); + + coe = 1.; + iter = 0; + maxiter = 20; + do { + ppa->c[0] = oldc[0] + coe * nx * len; + ppa->c[1] = oldc[1] + coe * ny * len; + ppa->c[2] = oldc[2] + coe * nz * len; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + + qual = MMG_caltet(mesh,sol,iel); + if ( !((qual < pt1->qual) || (qual < pt->qual /2.)) ) break; + list.qual[l] = qual; + + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxiter ); + if ( iter > maxiter) { + memcpy(ppa->c,oldc,3*sizeof(double)); + return(0); + } + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; +// if ( pt1->qual < declic ) +// MMG_kiudel(queue,iel); + } + return(1); + +} + + +int MMG_movevertex_iso(pMesh mesh,pSol sol,int k,int ib) { + pTetra pt,pt1; + pPoint ppa,ppb,p1,p2,p3; + List list; + int j,iadr,ipb,iter,maxiter,l,lon,iel,i1,i2,i3; + double hp,coe,crit; + double ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3]; + + assert(k); + assert(ib<4); + pt = &mesh->tetra[k]; + + ppa = &mesh->point[pt->v[ib]]; + iadr = (pt->v[ib]-1)*sol->offset + 1; + hp = sol->met[iadr]; + + /*compute normal*/ + i1 = pt->v[MMG_idir[ib][0]]; + i2 = pt->v[MMG_idir[ib][1]]; + i3 = pt->v[MMG_idir[ib][2]]; + p1 = &mesh->point[i1]; + p2 = &mesh->point[i2]; + p3 = &mesh->point[i3]; + + ax = p3->c[0] - p1->c[0]; + ay = p3->c[1] - p1->c[1]; + az = p3->c[2] - p1->c[2]; + + bx = p2->c[0] - p1->c[0]; + by = p2->c[1] - p1->c[1]; + bz = p2->c[2] - p1->c[2]; + + nx = (ay*bz - az*by); + ny = (az*bx - ax*bz); + nz = (ax*by - ay*bx); + + dd = sqrt(nx*nx+ny*ny+nz*nz); + dd = 1./dd; + nx *=dd; + ny *=dd; + nz *=dd; + len = 0; + for (j=0; j<3; j++) { + ipb = pt->v[ MMG_idir[ib][j] ]; + ppb = &mesh->point[ipb]; + + ax = ppb->c[0] - ppa->c[0]; + ay = ppb->c[1] - ppa->c[1]; + az = ppb->c[2] - ppa->c[2]; + + dd = sqrt(ax*ax +ay*ay +az*az); + len += dd/hp; + } + + dd = 1.0 / (double)3.; + len *= dd; + if(len > 0.) len = 1.0 / len; + else printf("MMG_movevertex len %e\n",len); + + memcpy(oldc,ppa->c,3*sizeof(double)); + + lon = MMG_boulep(mesh,k,ib,&list); + if(mesh->info.imprim < 0) if(lon < 4 && lon) printf("lon petit : %d\n",lon); + if(!lon) return(0); + + /*qual crit*/ + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + /* if ( (crit > 100/ALPHAD) ) { + crit *= 1.1; + } else + */ crit *= 0.99; + + coe = 1.; + iter = 0; + maxiter = 20; + do { + + ppa->c[0] = oldc[0] + coe * nx * len; + ppa->c[1] = oldc[1] + coe * ny * len; + ppa->c[2] = oldc[2] + coe * nz * len; + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + qual = MMG_caltet(mesh,sol,iel); + if ( qual > crit ) break; + list.qual[l] = qual; + + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxiter ); + if ( iter > maxiter) { + memcpy(ppa->c,oldc,3*sizeof(double)); + return(-2); + } + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; +// if ( pt1->qual < declic ) +// MMG_kiudel(queue,iel); + } + return(1); + +} + + +int MMG_movevertexbdry(pMesh mesh,pSol sol,int k,int ib) { + pTetra pt,pt1; + pPoint ppa,ppb,p1,p2,p3; + List list; + int j,ipb,iter,maxiter,l,lon,iel,i1,i2,i3; + double coe,crit; + double ax,ay,az,bx,by,bz,nx,ny,nz,dd,len,qual,oldc[3]; + + assert(k); + assert(ib<4); + pt = &mesh->tetra[k]; + + ppa = &mesh->point[pt->v[ib]]; + + /*compute normal*/ + i1 = pt->v[MMG_idir[ib][0]]; + i2 = pt->v[MMG_idir[ib][1]]; + i3 = pt->v[MMG_idir[ib][2]]; + p1 = &mesh->point[i1]; + p2 = &mesh->point[i2]; + p3 = &mesh->point[i3]; + + ax = p3->c[0] - p1->c[0]; + ay = p3->c[1] - p1->c[1]; + az = p3->c[2] - p1->c[2]; + + bx = p2->c[0] - p1->c[0]; + by = p2->c[1] - p1->c[1]; + bz = p2->c[2] - p1->c[2]; + + nx = (ay*bz - az*by); + ny = (az*bx - ax*bz); + nz = (ax*by - ay*bx); + + dd = sqrt(nx*nx+ny*ny+nz*nz); + dd = 1./dd; + nx *=dd; + ny *=dd; + nz *=dd; + len = 0; + for (j=0; j<3; j++) { + ipb = pt->v[ MMG_idir[ib][j] ]; + ppb = &mesh->point[ipb]; + + ax = ppb->c[0] - ppa->c[0]; + ay = ppb->c[1] - ppa->c[1]; + az = ppb->c[2] - ppa->c[2]; + + dd = ax*ax + ay*ay + az*az; + len += sqrt(dd); + } + + dd = 1.0 / (double)3.; + len = 1.0 / len; + len *= dd; + memcpy(oldc,ppa->c,3*sizeof(double)); + + lon = MMG_boulep(mesh,k,ib,&list); + if(mesh->info.imprim < 0 ) if(lon < 4 && lon) printf("lon petit : %d\n",lon); + if(!lon) return(0); + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + coe = 0.5; + iter = 0; + maxiter = 50; + do { + ppa->c[0] = oldc[0] + coe * nx * len; + ppa->c[1] = oldc[1] + coe * ny * len; + ppa->c[2] = oldc[2] + coe * nz * len; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + + qual = MMG_caltet(mesh,sol,iel); + if ( !((qual < crit)) ) break; + list.qual[l] = qual; + + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxiter ); + if ( iter > maxiter) { + memcpy(ppa->c,oldc,3*sizeof(double)); + return(0); + } + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; +// if ( pt1->qual < declic ) +// MMG_kiudel(queue,iel); + } + return(1); + +} + + diff --git a/contrib/mmg3d/build/sources/optbdry.c b/contrib/mmg3d/build/sources/optbdry.c new file mode 100644 index 0000000000..71152ccec5 --- /dev/null +++ b/contrib/mmg3d/build/sources/optbdry.c @@ -0,0 +1,272 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" +#define OCRIT 0.99 + +int MMG_movevertexbdry(pMesh mesh,pSol sol,int k,int ib); +int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef); + +int MMG_optbdry(pMesh mesh,pSol sol,int k) { + pTetra pt; + int ia,ib,i,*adja,iadr,ipb; + + + + pt = &mesh->tetra[k]; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + + /*essai de collapse du point qui n'est pas sur la peau*/ + for(i=0 ; i<4 ; i++) if(!adja[i]) break; + + ib = i; + ipb = pt->v[ib]; + if(!mesh->info.noinsert) { + for(i=1 ; i<4 ; i++) { + ia = (ib+i)%4; + if(MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD)) { + MMG_delPt(mesh,ipb); + break; + } + } + } else { + i=4; + } + + /*try to move the 4th vertex*/ + if(i==4) { +//if(k==402140) printf("colpoi refused, try move %d %d %d\n",k,ib,pt->v[ib]); + if(!MMG_movevertexbdry(mesh,sol,k,ib)) return(0); + return(2); + } + + return(1); + +} +int MMG_opt2peau(pMesh mesh,pSol sol,pQueue queue,int k,double declic) { + pTetra pt,pt1; + pPoint pa,pb,pc,pd; + List list; + double abx,aby,abz,acx,acy,acz,adx,ady,adz,v1,v2,v3,vol; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,h[6]; + double crit; + double s[4],dd,rapmin,rapmax; + int i,ia,ib,ic,id,iarmax,iarmin; + int lon,l,iel,ier; + + ier = 0; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) return(-1); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + pa = &mesh->point[ia]; + pb = &mesh->point[ib]; + pc = &mesh->point[ic]; + pd = &mesh->point[id]; + + /* volume */ + abx = pb->c[0] - pa->c[0]; + aby = pb->c[1] - pa->c[1]; + abz = pb->c[2] - pa->c[2]; + + acx = pc->c[0] - pa->c[0]; + acy = pc->c[1] - pa->c[1]; + acz = pc->c[2] - pa->c[2]; + + adx = pd->c[0] - pa->c[0]; + ady = pd->c[1] - pa->c[1]; + adz = pd->c[2] - pa->c[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + + /* max edge */ + h[0] = abx*abx + aby*aby + abz*abz; + h[1] = acx*acx + acy*acy + acz*acz; + h[2] = adx*adx + ady*ady + adz*adz; + + bcx = pc->c[0] - pb->c[0]; + bcy = pc->c[1] - pb->c[1]; + bcz = pc->c[2] - pb->c[2]; + + bdx = pd->c[0] - pb->c[0]; + bdy = pd->c[1] - pb->c[1]; + bdz = pd->c[2] - pb->c[2]; + + cdx = pd->c[0] - pc->c[0]; + cdy = pd->c[1] - pc->c[1]; + cdz = pd->c[2] - pc->c[2]; + + h[3] = bcx*bcx + bcy*bcy + bcz*bcz; + h[4] = bdx*bdx + bdy*bdy + bdz*bdz; + h[5] = cdx*cdx + cdy*cdy + cdz*cdz; + + /* face areas */ + dd = cdy*bdz - cdz*bdy; + s[0] = dd * dd; + dd = cdz*bdx - cdx*bdz; + s[0] = s[0] + dd * dd; + dd = cdx*bdy - cdy*bdx; + s[0] = s[0] + dd * dd; + s[0] = sqrt(s[0]); + + s[1] = sqrt(v1*v1 + v2*v2 + v3*v3); + + dd = bdy*adz - bdz*ady; + s[2] = dd * dd; + dd = bdz*adx - bdx*adz; + s[2] = s[2] + dd * dd; + dd = bdx*ady - bdy*adx; + s[2] = s[2] + dd * dd; + s[2] = sqrt(s[2]); + + dd = aby*acz - abz*acy; + s[3] = dd * dd; + dd = abz*acx - abx*acz; + s[3] = s[3] + dd * dd; + dd = abx*acy - aby*acx; + s[3] = s[3] + dd * dd; + s[3] = sqrt(s[3]); + + /* classification */ + rapmin = h[0]; + rapmax = h[0]; + iarmin = 0; + iarmax = 0; + for (i=1; i<6; i++) { + if ( h[i] < rapmin ) { + rapmin = h[i]; + iarmin = i; + } + else if ( h[i] > rapmax ) { + rapmax = h[i]; + iarmax = i; + } + } + rapmin = sqrt(rapmin); + rapmax = sqrt(rapmax); + + if(mesh->info.imprim < -9) printf("edge : %d %d\n",pt->v[MMG_iare[iarmax][0]],pt->v[MMG_iare[iarmax][1]]); + /*split edge*/ + lon = MMG_coquil(mesh,k,iarmax,&list); + if(mesh->info.imprim < 0) { + //printf("lon %d\n",lon); + //if(!lon) printf("colle peau, edge peau\n"); + } + + if(!lon) { + for(i=0 ; i<6 ; i++) { + lon = MMG_coquil(mesh,k,i,&list); + if ( lon > 2 ) { + if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) { + fprintf(stdout," ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n"); + MMG_kiufree(queue); + return(0); + } + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + //crit = min(1000/ALPHAD,crit*1.3); + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9); + if(ier) {/*printf("on a reussi a l'enlever par MMG_swap\n");*/break;} + if ( ier == 0 && !mesh->info.noinsert) { + crit = M_MIN(100./ALPHAD,crit*1.5); + ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic); + } + if(ier) {/*printf("on a reussi a l'enlever par split \n");*/break;} + + M_free(list.hedg.item); + } + } + + //M_free(list.hedg.item); + + if(ier) { + M_free(list.hedg.item); + return(1); + } + else return(0); + } else { + + if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) { + fprintf(stdout," ## MEMORY ALLOCATION PROBLEM MMG_optbdry.\n"); + MMG_kiufree(queue); + return(0); + } + if ( lon > 2 ) { + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + // crit = min(1000/ALPHAD,crit*1.3); + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,1e9); + if ( ier == 0 && !mesh->info.noinsert) { + crit = M_MIN(100./ALPHAD,crit*1.5); + ier = MMG_spledg(mesh,sol,queue,&list,lon,/*1.8**/crit,declic); + } + } + + + M_free(list.hedg.item); + if(ier) return(1); + else return(0); + } + return(1); + +} diff --git a/contrib/mmg3d/build/sources/optcoq.c b/contrib/mmg3d/build/sources/optcoq.c new file mode 100644 index 0000000000..c63a74d25f --- /dev/null +++ b/contrib/mmg3d/build/sources/optcoq.c @@ -0,0 +1,120 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define SCRIT 0.95 + + +/* optim coquilles 3 a 7 */ +int MMG_optcoq(pMesh mesh,pSol sol) { + pTetra pt,pt1; + pPoint p1,p2; + List list; + double crit; + int *adja,adj,iadr,i,j,k,ia,ib,jel,lon,ns,nss,it,maxtou; + char tabar; +int npp; + + maxtou = 10; + nss = 0; + it = 0; + + do { + ns = 0; + npp =0; + + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; +npp++; + /* mark internal edges */ + tabar = 0; + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + if ( !adj || pt->ref != mesh->tetra[adj].ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + } + if ( tabar == ALL_BDRY ) continue; + + /* longest edge */ + for (i=0; i<6; i++) { + if ( tabar & 1<<i ) continue; + + ia = pt->v[ MMG_iare[i][0] ]; + ib = pt->v[ MMG_iare[i][1] ]; + p1 = &mesh->point[ia]; + p2 = &mesh->point[ib]; + + lon = MMG_coquil(mesh,k,i,&list); + if ( lon < 3 || lon > 7 ) continue; + + /* qual crit */ + crit = pt->qual; + for (j=2; j<=lon; j++) { + jel = list.tetra[j] / 6; + pt1 = &mesh->tetra[jel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= SCRIT; + /* + if ( MMG_swapar(mesh,sol,0,k,i,&list,lon,crit) ) { + ns++; + break; + }*/ + } + } +printf(" prop %d swapped %d\n",npp,ns); + nss += ns; + } + while ( ns > 0 && ++it < maxtou ); + + return(nss); +} diff --git a/contrib/mmg3d/build/sources/optcte.c b/contrib/mmg3d/build/sources/optcte.c new file mode 100644 index 0000000000..6651abd33b --- /dev/null +++ b/contrib/mmg3d/build/sources/optcte.c @@ -0,0 +1,275 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define HQCOEF 0.45 +#define HCRIT 0.8 + +int MMG_optlentmp(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pPoint ppa,ppb; + pQueue queue; + List list; + double cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe; + double oldc[3],dd,dd1,dd2,len,lmi,lma; + double *mp,*mb; + int i,j,k,l,iel,lon,nm; + int ipa,ipb,nb,nk,npp,iadr,iter,maxtou; + + /* queueing tetrahedra */ + queue = MMG_kiuini(mesh,mesh->ne,declic,base); + assert(queue); + mesh->flag++; + + maxtou = 5; + nm = 0; + npp = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + else if ( ppa->flag > mesh->flag ) continue; + npp++; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point */ + iadr = (ipa-1)*sol->offset + 1; + mp = &sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + nb = 0; + cal = pt->qual; + lmi = LSHORT; + lma = LLONG; + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + if ( len < lmi ) lmi = len; + else if (len > lma ) lma = len; + + /* optimal point */ + len = 1.0 / sqrt(dd1); + cx += ppa->c[0] + ux * len; + cy += ppa->c[1] + uy * len; + cz += ppa->c[2] + uz * len; + nb++; + } + } + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd - ppa->c[0]; + cpy = cy*dd - ppa->c[1]; + cpz = cz*dd - ppa->c[2]; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + if ( cal > 10.0 / ALPHAD ) + ctg = cal * HCRIT; + else if ( cal > 5.0 / ALPHAD ) + ctg = cal * 0.95; + else + ctg = cal * 0.975; + memcpy(oldc,ppa->c,3*sizeof(double)); + +ctg = 1000. / ALPHAD; + + do { + ppa->c[0] = oldc[0] + coe * cpx; + ppa->c[1] = oldc[1] + coe * cpy; + ppa->c[2] = oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); + if ( cal > ctg ) break; + list.qual[l] = cal; + + /* check MMG_length */ + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + + if ( len < lmi || len > lma ) break; + } + if ( j < 3 ) break; + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = mesh->flag; + /*if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else if ( coe > 0.1 ) + MMG_kiuput(queue,iel); */ + } + + /* interpol metric */ + ppa->flag = mesh->flag + 1; + nm++; + break; + } + } + while ( k ); + + if ( mesh->info.imprim < -4 ) + fprintf(stdout," %7d PROPOSED %7d MOVED\n",npp,nm); + + MMG_kiufree(queue); + return(nm); +} + + + + + +int MMG_optcte(pMesh mesh,pSol sol) { + double declicw; + double declic; + int base,nm,ns,it,maxtou,alert,nw; + + + alert = 0; + + /* optim coquil */ + declic = 1. / ALPHAD; + maxtou = 10; + base = -1; + it = 0; + + do { + + nw = 0; + declicw = 5./ALPHAD; +// if (!mesh->info.noswap) nw = MMG_opttyp(mesh,sol,declicw,&alert); + + nm = MMG_optlentmp(mesh,sol,declic,-1); +// ns = 0; +// if ( !alert && !mesh->info.noswap ) { +// ns = MMG_cendel(mesh,sol,declic,base); +// if ( ns < 0 ) { +// alert = 1; +// ns = -ns; +// } +// } +// base = ++mesh->flag; +// +// if ( !mesh->disp ) if(it<2) MMG_optlap(mesh,sol); + +ns = 0; + if ( mesh->info.imprim && nm+ns ) + fprintf(stdout," %8d MOVED %8d SWAPPED\n",nm,ns); + } + while ( nm > 0.01*mesh->np && ++it < maxtou ); + + + MMG_outqua(mesh,sol); + MMG_prilen(mesh,sol); + puts("-------- APPEL MMG_optra4"); + MMG_optra4(mesh,sol); + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/optlap.c b/contrib/mmg3d/build/sources/optlap.c new file mode 100644 index 0000000000..6a81bbba3a --- /dev/null +++ b/contrib/mmg3d/build/sources/optlap.c @@ -0,0 +1,284 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define LLAMBDA 0.33 /*0.33*/ +#define LMU 0.331 /*0.34*/ + +int MMG_optlap(pMesh mesh,pSol sol) { + pTetra pt,pt1; + pPoint ppt,pptb,ppta; + pDispl pdisp; + List list; + int it,i,k,lon,l,iel,ipt; + int maxiter,ipta,iptb,ipt0,ipt1,ipt2,ipt3; + double vol,ax,ay,az,bx,by,bz; + double *nv,res,dd,ox,oy,oz,declic; + + if(!mesh->disp) { + mesh->disp = (pDispl)M_calloc(1,sizeof(Displ),"MMG_zaldy.displ"); + assert(mesh->disp); + mesh->disp->mv = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_zaldy.displ"); + assert(mesh->disp->mv); + mesh->disp->alpha = (short*)M_calloc(mesh->npmax+1,sizeof(short),"MMG_zaldy.displ"); + assert(mesh->disp->alpha); + } + maxiter = 3; + nv = (double*)M_calloc(mesh->np+1,3*sizeof(double),"movlap.nv"); + assert(nv); + + pdisp = mesh->disp; + + it = 1; + declic = 3./ALPHAD; + do { + + /*initialisation*/ + for(i = 1 ; i<=mesh->np ; i++) { + ppt = &mesh->point[i]; + pdisp->alpha[i] = 0; + pdisp->mv[3*(i-1) + 1 + 0] = 0.; + pdisp->mv[3*(i-1) + 1 + 1] = 0.; + pdisp->mv[3*(i-1) + 1 + 2] = 0.; + + } + + /*1st stage : laplacian*/ + for(k = 1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if (!pt->v[0]) continue; + if (pt->qual > declic) continue; + + for(i=0 ; i<6 ; i++) { + ipta = pt->v[MMG_iare[i][0]]; + ppta = &mesh->point[ipta]; + + iptb = pt->v[MMG_iare[i][1]]; + pptb = &mesh->point[iptb]; + + if(!(ppta->tag & M_BDRY)) { + pdisp->mv[3*(ipta-1) + 1 + 0] += pptb->c[0]; + pdisp->mv[3*(ipta-1) + 1 + 1] += pptb->c[1]; + pdisp->mv[3*(ipta-1) + 1 + 2] += pptb->c[2]; + pdisp->alpha[ipta]++; + } + if(!(pptb->tag & M_BDRY)) { + pdisp->mv[3*(iptb-1) + 1 + 0] += ppta->c[0]; + pdisp->mv[3*(iptb-1) + 1 + 1] += ppta->c[1]; + pdisp->mv[3*(iptb-1) + 1 + 2] += ppta->c[2]; + pdisp->alpha[iptb]++; + } + } + } + + for(i=1 ; i<=mesh->np ; i++) { + ppt = &mesh->point[i]; + if(pdisp->alpha[i]) { + dd = 1./(double) pdisp->alpha[i]; + pdisp->mv[3*(i-1) + 1 + 0] *= dd; + pdisp->mv[3*(i-1) + 1 + 1] *= dd; + pdisp->mv[3*(i-1) + 1 + 2] *= dd; + nv[3*(i-1) + 1] = ppt->c[0] + LLAMBDA * (ppt->c[0] - pdisp->mv[3*(i-1) + 1 + 0]); + nv[3*(i-1) + 2] = ppt->c[1] + LLAMBDA * (ppt->c[1] - pdisp->mv[3*(i-1) + 1 + 1]); + nv[3*(i-1) + 3] = ppt->c[2] + LLAMBDA * (ppt->c[2] - pdisp->mv[3*(i-1) + 1 + 2]); + } else { + nv[3*(i-1) + 1] = ppt->c[0]; + nv[3*(i-1) + 2] = ppt->c[1]; + nv[3*(i-1) + 3] = ppt->c[2]; + + } + pdisp->alpha[i] = 0; + pdisp->mv[3*(i-1) + 1 + 0] = 0.; + pdisp->mv[3*(i-1) + 1 + 1] = 0.; + pdisp->mv[3*(i-1) + 1 + 2] = 0.; + + } + + /*2nd stage : anti-laplacian*/ + for(k = 1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if (!pt->v[0]) continue; + if (pt->qual > declic) continue; + + for(i=0 ; i<6 ; i++) { + ipta = pt->v[MMG_iare[i][0]]; + ppta = &mesh->point[ipta]; + + iptb = pt->v[MMG_iare[i][1]]; + pptb = &mesh->point[iptb]; + + if(!(ppta->tag & M_BDRY)) { + pdisp->mv[3*(ipta-1) + 1 + 0] += nv[3*(iptb-1) + 1]; + pdisp->mv[3*(ipta-1) + 1 + 1] += nv[3*(iptb-1) + 2]; + pdisp->mv[3*(ipta-1) + 1 + 2] += nv[3*(iptb-1) + 3]; + pdisp->alpha[ipta]++; + } + if(!(pptb->tag & M_BDRY)) { + pdisp->mv[3*(iptb-1) + 1 + 0] += nv[3*(ipta-1) + 1]; + pdisp->mv[3*(iptb-1) + 1 + 1] += nv[3*(ipta-1) + 2]; + pdisp->mv[3*(iptb-1) + 1 + 2] += nv[3*(ipta-1) + 3]; + pdisp->alpha[iptb]++; + } + } + } + + res= 0.; + for(i=1 ; i<=mesh->np ; i++) { + ppt = &mesh->point[i]; + if(pdisp->alpha[i]) { + dd = 1./(double) pdisp->alpha[i]; + pdisp->mv[3*(i-1) + 1 + 0] *= dd; + pdisp->mv[3*(i-1) + 1 + 1] *= dd; + pdisp->mv[3*(i-1) + 1 + 2] *= dd; + ox = nv[3*(i-1) + 1]; + oy = nv[3*(i-1) + 2]; + oz = nv[3*(i-1) + 3]; + nv[3*(i-1) + 1] = nv[3*(i-1) + 1] - LMU * (nv[3*(i-1) + 1] - pdisp->mv[3*(i-1) + 1 + 0]); + nv[3*(i-1) + 2] = nv[3*(i-1) + 2] - LMU * (nv[3*(i-1) + 2] - pdisp->mv[3*(i-1) + 1 + 1]); + nv[3*(i-1) + 3] = nv[3*(i-1) + 3] - LMU * (nv[3*(i-1) + 3] - pdisp->mv[3*(i-1) + 1 + 2]); + + dd = (nv[3*(i-1) + 1]-ox)*(nv[3*(i-1) + 1]-ox) + + (nv[3*(i-1) + 2]-oy)*(nv[3*(i-1) + 2]-oy) + + (nv[3*(i-1) + 3]-oz)*(nv[3*(i-1) + 3]-oz); + res +=dd; + + } + + + pdisp->alpha[i] = 0; + pdisp->mv[3*(i-1) + 1 + 0] = 0.; + pdisp->mv[3*(i-1) + 1 + 1] = 0.; + pdisp->mv[3*(i-1) + 1 + 2] = 0.; + } +/* printf("---------- iter %d res %e\r",it,res); + fflush(stdout); +*/ + /*check new coor*/ + for(k = 1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) continue; + + for(i=0 ; i<4 ; i++) { + ipt = pt->v[i]; + ppt = &mesh->point[ipt]; + if(ppt->tag & M_BDRY) continue; + if(ppt->tmp2) continue; + ppt->tmp2 = 1; + lon = MMG_boulep(mesh,k,i,&list); + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + ipt0 = 3*(pt1->v[0] - 1); + ipt1 = 3*(pt1->v[1] - 1); + ipt2 = 3*(pt1->v[2] - 1); + ipt3 = 3*(pt1->v[3] - 1); + + ax = nv[ipt2 + 1] - nv[ipt0 + 1]; + ay = nv[ipt2 + 2] - nv[ipt0 + 2]; + az = nv[ipt2 + 3] - nv[ipt0 + 3]; + + bx = nv[ipt3 + 1] - nv[ipt0 + 1]; + by = nv[ipt3 + 2] - nv[ipt0 + 2]; + bz = nv[ipt3 + 3] - nv[ipt0 + 3]; + + vol = (nv[ipt1 + 1] - nv[ipt0 + 1]) * (ay*bz - az*by) \ + + (nv[ipt1 + 2] - nv[ipt0 + 2]) * (az*bx - ax*bz) \ + + (nv[ipt1 + 3] - nv[ipt0 + 3]) * (ax*by - ay*bx); + if(vol < 0) {/*printf("reject1 %e\n",vol);*/break;} + } + if(l<=lon) { + memcpy(&pdisp->mv[3*(ipt-1) + 1],ppt->c,3*sizeof(double)); + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + pt1 = &mesh->tetra[iel]; + ipt0 = 3*(pt1->v[0] - 1); + ipt1 = 3*(pt1->v[1] - 1); + ipt2 = 3*(pt1->v[2] - 1); + ipt3 = 3*(pt1->v[3] - 1); + + ax = nv[ipt2 + 1] - nv[ipt0 + 1]; + ay = nv[ipt2 + 2] - nv[ipt0 + 2]; + az = nv[ipt2 + 3] - nv[ipt0 + 3]; + + bx = nv[ipt3 + 1] - nv[ipt0 + 1]; + by = nv[ipt3 + 2] - nv[ipt0 + 2]; + bz = nv[ipt3 + 3] - nv[ipt0 + 3]; + + vol = (nv[ipt1 + 1] - nv[ipt0 + 1]) * (ay*bz - az*by) \ + + (nv[ipt1 + 2] - nv[ipt0 + 2]) * (az*bx - ax*bz) \ + + (nv[ipt1 + 3] - nv[ipt0 + 3]) * (ax*by - ay*bx); + if(vol < 0) {/*printf("reject %e\n",vol);*/break;} + } + if(l<=lon) break; + } + } + if(i<4) break; + } + if(k > mesh->ne) { + /*update coor*/ + for(i=1 ; i<=mesh->np ; i++) { + ppt = &mesh->point[i]; + ppt->c[0] = nv[3*(i-1) + 1]; + ppt->c[1] = nv[3*(i-1) + 2]; + ppt->c[2] = nv[3*(i-1) + 3]; + } + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) continue; + pt->qual = MMG_caltet(mesh,sol,k); + } + if(mesh->info.imprim < 0) fprintf(stdout," LAPLACIAN : %8f\n",res); + } else { + if(mesh->info.imprim < 0) fprintf(stdout," NO LAPLACIAN\n"); + break; + } + if(res<1e-5) break; + + } while(it++ < maxiter); + + M_free(nv); + return(1); +} diff --git a/contrib/mmg3d/build/sources/optlen.c b/contrib/mmg3d/build/sources/optlen.c new file mode 100644 index 0000000000..ab8b07a26a --- /dev/null +++ b/contrib/mmg3d/build/sources/optlen.c @@ -0,0 +1,610 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define HQCOEF 0.9 +#define HCRIT 0.98 + +double MMG_rao(pMesh mesh,int k,int inm); +int MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pPoint ppa,ppb; + pQueue queue; + List list; + double cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe; + double oldc[3],dd,dd1,dd2,len,lmi,lma; + double *mp,*mb,wcal; + int i,j,k,l,iel,lon,nm; + int ipa,ipb,nb,nk,npp,iadr,iter,maxtou; + + /* queueing tetrahedra */ + queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1); + assert(queue); + + maxtou = 3; + nm = 0; + npp = 0; + wcal = 5. / ALPHAD; + + do { + k = MMG_kiupop(queue); + if ( !k ) break; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->flag != base - 1 ) continue; + + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + else if ( ppa->flag != base - 1) continue; + npp++; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point */ + iadr = (ipa-1)*sol->offset + 1; + mp = &sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + nb = 0; + cal = pt->qual; + lmi = LSHORT; + lma = LLONG; + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + if ( len < lmi ) lmi = len; + else if (len > lma ) lma = len; + + /* optimal point */ + len = 1.0 / sqrt(dd1); + cx += ppa->c[0] + ux * len; + cy += ppa->c[1] + uy * len; + cz += ppa->c[2] + uz * len; + nb++; + } + } + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd - ppa->c[0]; + cpy = cy*dd - ppa->c[1]; + cpz = cz*dd - ppa->c[2]; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + /*if ( cal > 10.0 / ALPHAD ) + ctg = cal * HCRIT; + else*/ + ctg = cal * HCRIT;//0.975; + memcpy(oldc,ppa->c,3*sizeof(double)); + + do { + ppa->c[0] = oldc[0] + coe * cpx; + ppa->c[1] = oldc[1] + coe * cpy; + ppa->c[2] = oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); + if ( cal > ctg ) break; + list.qual[l] = cal; + + /* check length */ + /* for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + + if ( len < lmi || len > lma ) break; + } + if ( j < 3 ) break;*/ + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + ppa->flag = base - 2; + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = base; + for(i=0; i<4; i++) mesh->point[pt1->v[i]].flag = base; + if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else if ( coe > 0.1 ) + MMG_kiuput(queue,iel); + } + + /* interpol metric */ + ppa->flag = base + 1; + nm++; + break; + } + } + while ( k ); + + if ( mesh->info.imprim < -4 ) + fprintf(stdout," %7d PROPOSED %7d MOVED\n",npp,nm); + + MMG_kiufree(queue); + return(nm); +} + + +/* optimise using heap */ +int MMG_optlen_iso(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pPoint ppa,ppb; + pQueue queue; + List list; + double oldc[3],cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe,dd,len; + double hb,hp,*ca,*cb; + int i,j,k,l,iel,lon,nm; + int ipa,ipb,nb,nk,npp,iadr,iter,maxtou; +int nrj; +double tmp1,tmp2,tmp3; + /* queue on quality */ + queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1); + assert(queue); + + maxtou = 10; + nm = 0; + npp = 0; +nrj = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + npp++; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + // else if ( pt->flag != base - 1 ) continue; + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + // else if ( ppa->flag != base - 1 ) continue; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point */ + ca = &ppa->c[0]; + iadr = (ipa-1)*sol->offset + 1; + hp = sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + nb = 0; + cal = pt->qual; + for (l=1 ; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + tmp1 = 0; + tmp2 = 0; + tmp3 = 0; + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; +/*if(ppb->mark < 0) continue; +ppb->mark = -ppb->mark;*/ +//printf("on prend en compte point %d\n",ipb); + cb = &ppb->c[0]; + iadr = (ipb-1)*sol->offset + 1; + hb = sol->met[iadr]; + + len = MMG_length(ca,cb,&hp,&hb); + +/*len = MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][0]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][1]]].c[0]),&hp,&hb); +len += MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][0]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][2]]].c[0]),&hp,&hb); +len += MMG_length(&(mesh->point[pt1->v[MMG_idir[nk][1]]].c[0]),&(mesh->point[pt1->v[MMG_idir[nk][2]]].c[0]),&hp,&hb); +len /= 3.; +len = 1./len; +len *= MMG_length(ca,cb,&hp,&hb); */ + /* optimal point */ + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + cx += ppa->c[0] + ux*(1. - 1./len);//ux * len; + cy += ppa->c[1] + uy*(1. - 1./len);//uy * len; + cz += ppa->c[2] + uz*(1. - 1./len);//uz * len; + tmp1 +=ux*(1. - 1./len); + tmp2 +=uy*(1. - 1./len); + tmp3 +=uz*(1. - 1./len); +/*memcpy(oldc,ppa->c,3*sizeof(double)); +ppa->c[0] = oldc[0] + ux*(1. - 1./len);//ppb->c[0] - (ux/MMG_length(oldc,cb,&hp,&hb))*len; +ppa->c[1] = oldc[1] + uy*(1. - 1./len);//ppb->c[1] - (uy/MMG_length(oldc,cb,&hp,&hb))*len; +ppa->c[2] = oldc[2] + uz*(1. - 1./len);//ppb->c[2] - (uz/MMG_length(oldc,cb,&hp,&hb))*len; +printf("%d len %e (%e)\n",j,MMG_length(ca,cb,&hp,&hb),len); +memcpy(ppa->c,oldc,3*sizeof(double)); + */ + nb++; + } +/*check amelioration*/ +/*memcpy(oldc,ppa->c,3*sizeof(double)); +ppa->c[0] = oldc[0] + tmp1/3.; +ppa->c[1] = oldc[1] + tmp2/3.; +ppa->c[2] = oldc[2] + tmp3/3.; +if(MMG_caltet(mesh,sol,iel) > pt1->qual) { + printf("oups %d -- cal of %d ( %d ) %e > %e\n",nb,iel,ipa,pt1->qual,MMG_caltet(mesh,sol,iel)); + + //exit(0); + } +else { +//printf("%d -- cal of %d ( %d ) %e > %e\n",nb,iel,ipa,pt1->qual,MMG_caltet(mesh,sol,iel)); +} +memcpy(ppa->c,oldc,3*sizeof(double)); +*/ + } +/*for (l=1 ; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + ppb->mark = abs(ppb->mark); + } +} */ + + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd - ppa->c[0]; + cpy = cy*dd - ppa->c[1]; + cpz = cz*dd - ppa->c[2]; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + if(cal > 100./ALPHAD) { + ctg = 0.99 * cal; + } else { + ctg = cal * HCRIT; + } + memcpy(oldc,ppa->c,3*sizeof(double)); + do { + ppa->c[0] =/* (1. - coe) * */oldc[0] + coe * cpx; + ppa->c[1] =/* (1. - coe) * */oldc[1] + coe * cpy; + ppa->c[2] =/* (1. - coe) * */oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); + if ( cal > ctg ) break; + list.qual[l] = cal; + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + ppa->flag = base - 2; + //if(k==154529) printf("cal(%d) %e %e %e\n",iel,cal,ctg,ctg/0.99); + /*exit(0);*/ nrj++; + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = base; + for(i=0; i<4; i++) mesh->point[pt1->v[i]].flag = base; + //if(iel==154529) printf("on a traite %d (%d) %e %d\n",iel,k,pt1->qual,iter); + + if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else if ( coe > 0.1 ) + MMG_kiuput(queue,iel); + } + + /* interpol metric */ + ppa->flag = base + 1; + nm++; + break; + } + } + while ( k ); + + if ( mesh->info.imprim < - 4 ) + fprintf(stdout," %7d PROPOSED %7d MOVED %d REJ \n",npp,nm,nrj); + + MMG_kiufree(queue); + return(nm); +} + +/* optimise using heap : point position on normal*/ +int MMG_optlen_iso_new(pMesh mesh,pSol sol,double declic,int base) { + pTetra pt,pt1; + pPoint ppa,ppb,p1,p2,p3; + pQueue queue; + List list; + double oldc[3],cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe,dd,len; + double hb,hp,*ca,ax,ay,az,bx,by,bz,nx,ny,nz; + int i,j,k,l,iel,lon,nm; + int ipa,ipb,nb,nk,npp,iadr,iter,maxtou; +int nrj,i1,i2,i3; +//double co1,co2,ddd; + /* queue on quality */ + queue = MMG_kiuini(mesh,mesh->ne,declic,base - 1); + assert(queue); + + maxtou = 3; + nm = 0; + npp = 0; +nrj = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + npp++; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + //else if ( pt->flag != base - 1 ) continue; + + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + //else if ( ppa->flag != base - 1 ) continue; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point : length 1 sur la normal a la face*/ + ca = &ppa->c[0]; + iadr = (ipa-1)*sol->offset + 1; + hp = sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + ux = 0.0; + uy = 0.0; + uz = 0.0; + nb = 0; + cal = pt->qual; + for (l=1 ; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + +//printf("lon %d cal %e %e\n",kel,pt1->qual,MMG_caltet_iso(mesh,sol,iel)); +//printf("boule : %d : %e %e %e\n",l,pt1->qual,pt1->qual*ALPHAD,MMG_rao(mesh,iel,0)); + + /*compute normal*/ + i1 = pt->v[MMG_idir[nk][0]]; + i2 = pt->v[MMG_idir[nk][1]]; + i3 = pt->v[MMG_idir[nk][2]]; + p1 = &mesh->point[i1]; + p2 = &mesh->point[i2]; + p3 = &mesh->point[i3]; + + ax = p3->c[0] - p1->c[0]; + ay = p3->c[1] - p1->c[1]; + az = p3->c[2] - p1->c[2]; + + bx = p2->c[0] - p1->c[0]; + by = p2->c[1] - p1->c[1]; + bz = p2->c[2] - p1->c[2]; + + nx = (ay*bz - az*by); + ny = (az*bx - ax*bz); + nz = (ax*by - ay*bx); + + dd = sqrt(nx*nx+ny*ny+nz*nz); + dd = 1./dd; + nx *= dd; + ny *= dd; + nz *= dd; + + len = 0; + ux = 0; + uy = 0; + uz = 0; + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + iadr = (ipb-1)*sol->offset + 1; + hb = sol->met[iadr]; + + ax = ppb->c[0] - ppa->c[0]; + ay = ppb->c[1] - ppa->c[1]; + az = ppb->c[2] - ppa->c[2]; + + /* centre de gravite de la face*/ + ux += ppb->c[0]; + uy += ppb->c[1]; + uz += ppb->c[2]; + + dd = sqrt(ax*ax +ay*ay +az*az); + len += dd/hb; + } + dd = 1.0 / (double)3.; + len *= dd; + ux *= dd; + uy *= dd; + uz *= dd; + if(len > 0.) len = 1.0 / len; + else printf("optlennew len %e\n",len); + + /* optimal point */ + cx += ux + nx * len; + cy += uy + ny * len; + cz += uz + nz * len; + nb++; + + } + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd; + cpy = cy*dd; + cpz = cz*dd; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + if(cal > 100./ALPHAD) { + ctg = 0.99 * cal; + } else { + ctg = cal * HCRIT; + } + maxtou = 10; + memcpy(oldc,ppa->c,3*sizeof(double)); + do { + ppa->c[0] = (1. - coe) *oldc[0] + coe * cpx; + ppa->c[1] = (1. - coe) *oldc[1] + coe * cpy; + ppa->c[2] = (1. - coe) *oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); +//printf("l %d cal %e %e\n",l,cal,MMG_rao(mesh,iel,0)); + if ( cal > ctg ) break; + list.qual[l] = cal; + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + ppa->flag = base - 2; +//printf("arg cal %e %e %e\n",cal,ctg,ctg/0.98); + nrj++; + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = base; + for(i=0; i<4; i++) mesh->point[pt1->v[i]].flag = base; + + if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else if ( coe > 0.1 ) + MMG_kiuput(queue,iel); + } + + /* interpol metric */ + ppa->flag = base + 1; + nm++; + break; + } + } + while ( k ); + + if ( mesh->info.imprim < - 4 ) + fprintf(stdout," %7d PROPOSED %7d MOVED %d REJ \n",npp,nm,nrj); + + MMG_kiufree(queue); + return(nm); +} diff --git a/contrib/mmg3d/build/sources/optlentet.c b/contrib/mmg3d/build/sources/optlentet.c new file mode 100644 index 0000000000..380ed42c2f --- /dev/null +++ b/contrib/mmg3d/build/sources/optlentet.c @@ -0,0 +1,349 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define HQCOEF 0.45 +#define HCRIT 0.8 + + +int MMG_optlentet_ani(pMesh mesh,pSol sol,pQueue queue,double declic,int base,int k) { + pTetra pt,pt1; + pPoint ppa,ppb; + List list; + double cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe; + double oldc[3],dd,dd1,dd2,len,lmi,lma; + double *mp,*mb; + int i,j,l,iel,lon; + int ipa,ipb,nb,nk,iadr,iter,maxtou; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) return(0); + + + maxtou = 2; + + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + else if ( ppa->flag > mesh->flag ) continue; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point */ + iadr = (ipa-1)*sol->offset + 1; + mp = &sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + nb = 0; + cal = pt->qual; + lmi = LSHORT; + lma = LLONG; + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + if ( len < lmi ) lmi = len; + else if (len > lma ) lma = len; + + /* optimal point */ + len = 1.0 / sqrt(dd1); + cx += ppa->c[0] + ux * len; + cy += ppa->c[1] + uy * len; + cz += ppa->c[2] + uz * len; + nb++; + } + } + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd - ppa->c[0]; + cpy = cy*dd - ppa->c[1]; + cpz = cz*dd - ppa->c[2]; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + if ( cal > 10.0 / ALPHAD ) + ctg = cal * HCRIT; + else if ( cal > 5.0 / ALPHAD ) + ctg = cal * 0.95; + else + ctg = cal * 0.975; + memcpy(oldc,ppa->c,3*sizeof(double)); + + do { + ppa->c[0] = oldc[0] + coe * cpx; + ppa->c[1] = oldc[1] + coe * cpy; + ppa->c[2] = oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); + if ( cal > ctg ) break; + list.qual[l] = cal; + + /* check length */ + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + ux = ppb->c[0] - ppa->c[0]; + uy = ppb->c[1] - ppa->c[1]; + uz = ppb->c[2] - ppa->c[2]; + + dd1 = mp[0]*ux*ux + mp[3]*uy*uy + mp[5]*uz*uz \ + + 2.0*(mp[1]*ux*uy + mp[2]*ux*uz + mp[4]*uy*uz); + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy + mb[2]*ux*uz + mb[4]*uy*uz); + len = 0.5*(dd1+dd2); + + if ( len < lmi || len > lma ) break; + } + if ( j < 3 ) break; + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = mesh->flag; + if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else + MMG_kiuput(queue,iel); + } + + /* interpol metric */ + ppa->flag = mesh->flag + 1; + break; + } + + + if(i!=4) return(1); + + return(0); +} + + +int MMG_optlentet_iso(pMesh mesh,pSol sol,pQueue queue,double declic,int base,int k) { + pTetra pt,pt1; + pPoint ppa,ppb; + List list; + double cal,ctg,cx,cy,cz,ux,uy,uz,cpx,cpy,cpz,coe; + double oldc[3],dd,len,lmi,lma,*ca,*cb,hp,hb; + int i,j,l,iel,lon; + int ipa,ipb,nb,nk,iadr,iter,maxtou; + + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) return(0); + maxtou = 5; + + for (i=0; i<4; i++) { + ipa = pt->v[i]; + ppa = &mesh->point[ipa]; + if ( ppa->tag & M_BDRY ) continue; + else if ( ppa->flag > mesh->flag ) continue; + + lon = MMG_boulep(mesh,k,i,&list); + if ( lon < 4 ) continue; + + /* optimal point */ + ca = &ppa->c[0]; + iadr = (ipa-1)*sol->offset + 1; + hp = sol->met[iadr]; + cx = 0.0; + cy = 0.0; + cz = 0.0; + nb = 0; + cal = pt->qual; + lmi = 0.6; //LSHORT; + lma = 1.4; //LLONG; + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > cal ) cal = pt1->qual; + + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + iadr = (ipb-1)*sol->offset + 1; + hb = sol->met[iadr]; + cb = &ppb->c[0]; + len = MMG_length(ca,cb,&hp,&hb); + if ( len < lmi ) lmi = len; + else if ( len > lma ) lma = len; + + /* optimal point */ + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + + len = 1.0 / len; + cx += ca[0] + ux * len; + cy += ca[1] + uy * len; + cz += ca[2] + uz * len; + nb++; + } + } + if ( nb < 3 ) continue; + dd = 1.0 / (double)nb; + cpx = cx*dd - ca[0]; + cpy = cy*dd - ca[1]; + cpz = cz*dd - ca[2]; + + /* adjust position */ + coe = HQCOEF; + iter = 1; + if ( cal > 10.0 / ALPHAD ) + ctg = cal * HCRIT; + else if ( cal > 5.0 / ALPHAD ) + ctg = cal * 0.95; + else + ctg = cal * 0.9975; + memcpy(oldc,ppa->c,3*sizeof(double)); + + do { + ca[0] = oldc[0] + coe * cpx; + ca[1] = oldc[1] + coe * cpy; + ca[2] = oldc[2] + coe * cpz; + + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + + cal = MMG_caltet(mesh,sol,iel); + if ( cal > ctg ) break; + list.qual[l] = cal; + + /* check length */ + for (j=0; j<3; j++) { + ipb = pt1->v[ MMG_idir[nk][j] ]; + ppb = &mesh->point[ipb]; + cb = &ppb->c[0]; + + iadr = (ipb-1)*sol->offset + 1; + hb = sol->met[iadr]; + len = MMG_length(ca,cb,&hp,&hb); + if ( len < lmi || len > lma ) { + break; + } + } + if ( j < 3 ) break; + } + if ( l > lon ) break; + coe *= 0.5; + } + while ( ++iter <= maxtou ); + if ( iter > maxtou ) { + memcpy(ppa->c,oldc,3*sizeof(double)); + continue; + } + + /* update tetra */ + for (l=1; l<=lon; l++) { + iel = list.tetra[l] >> 2; + nk = list.tetra[l] % 4; + pt1 = &mesh->tetra[iel]; + pt1->qual = list.qual[l]; + pt1->flag = mesh->flag; + + if ( pt1->qual < declic ) + MMG_kiudel(queue,iel); + else + MMG_kiuput(queue,iel); + } + + + /* interpol metric */ + ppa->flag = mesh->flag + 1; + break; + } + + + if(i!=4) return(1); + + return(0); +} diff --git a/contrib/mmg3d/build/sources/optra4.c b/contrib/mmg3d/build/sources/optra4.c new file mode 100644 index 0000000000..0b0a665067 --- /dev/null +++ b/contrib/mmg3d/build/sources/optra4.c @@ -0,0 +1,106 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_pretreat(pMesh ,pSol ,double ,int *); + +int MMG_optra4(pMesh mesh,pSol sol) { + double declicw; + double declic; + int base,nm,ns,it,maxtou,alert,nw,nwold,k; + + /* optim coquil */ + alert = 0; + maxtou = 20;//0; + it = 0; + + MMG_caltet = ( sol->offset==6 ) ? MMG_caltet_ani:MMG_caltet_iso; + MMG_caltet2 = ( sol->offset==6 ) ? MMG_caltet2_ani:MMG_caltet2_iso; + + for (k=1; k<=mesh->ne; k++) { + mesh->tetra[k].flag = mesh->flag; + mesh->tetra[k].qual = MMG_caltet(mesh,sol,k); + } + for (k=1; k<=mesh->np; k++) mesh->point[k].flag = mesh->flag; + declicw = 5./ALPHAD; + declic = 1.5/ ALPHAD; + + do { + base = ++mesh->flag; +//MMG_ratio(mesh,sol,NULL); + ns = 0; + if ( !alert && !mesh->info.noswap ) { + ns = MMG_cendel(mesh,sol,declic,base); + if ( ns < 0 ) { + alert = 1; + ns = -ns; + } + } + nw = 0; + /*if (!mesh->info.noinsert) nw = MMG_pretreat(mesh,sol,declicw,&alert); + */ + /*sur des surfaces courbes, il existe des tetras ayant 4 points de peau avec Q=3*/ + if ( it < 10 ) { + nwold = nw; + nw += MMG_opttyp(mesh,sol,declicw,&alert); + declicw *= 1.05; + + } + nm = 0; + if (!mesh->info.nomove) { + nm = MMG_optlen(mesh,sol,declic,base); + } + + //if(!mesh->info.nomove && it<2) MMG_optlap(mesh,sol); + if ( mesh->info.imprim && nw+ns+nm ) + fprintf(stdout," %8d IMPROVED %8d SWAPPED %8d MOVED\n",nw,ns,nm); + } + //while ( (ns && ((ns > 0.005*mesh->ne /*&& nwold > nw*/) || it < 5)) && ++it < maxtou ); + while ( ns+nm && ++it < maxtou ); + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/opttet.c b/contrib/mmg3d/build/sources/opttet.c new file mode 100644 index 0000000000..eabe29da11 --- /dev/null +++ b/contrib/mmg3d/build/sources/opttet.c @@ -0,0 +1,133 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_swaptet(pMesh mesh,pSol sol,pQueue queue, double declic,int iel); + +int MMG_opttet(pMesh mesh,pSol sol) { + pQueue queue; + double declic; + int base,nm,ns,it,maxtou,alert,ier,k; +double worst; +double declicw; +int iterworst,nw; + worst = 1e20; + + + + /* optim tet */ + alert = 0; + declic = 1.7 / ALPHAD; //ALPHAD cte pour qualite interne + maxtou = 10; + base = -1; + it = 0; + + do { + ns = 0; + nm = 0; + + iterworst = 0; + nw = 0; + declicw = 9./ALPHAD; + do { +//printf("--------------- iter %d : declicw %e\n",iterworst,declicw*ALPHAD); +//MMG_outqua(mesh,sol); + if (!mesh->info.noswap) + nw = MMG_opttyp(mesh,sol,declicw,&alert); + } while((iterworst++ < 0) && nw); + MMG_outqua(mesh,sol); + puts(" "); + + worst = MMG_priworst(mesh,sol); + + /* queueing tetrahedra */ + queue = MMG_kiuini(mesh,mesh->ne,declic,base); + assert(queue); + mesh->flag++; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + /*try MMG_swap*/ + ier = 0; + if((!mesh->info.noswap)) ier = MMG_swaptet(mesh,sol,queue,declic,k); + if(ier < 0) { + alert = 1; + } else if(ier) { + ns++; + continue; + } + + /*try move*/ + if(MMG_optlentet(mesh,sol,queue,declic,base,k)) { + nm++; + continue; + } + + } + while ( k ); + + MMG_kiufree(queue); + base = ++mesh->flag; + + if ( mesh->info.imprim && nm+ns ) + fprintf(stdout," %8d MOVED %8d SWAPPED\n",nm,ns); + } + while ( nm > 0.01*mesh->np && ++it < maxtou ); + +printf("------------------------ on est arrive a maxtou ?: %d %d\n",it,maxtou); + worst = MMG_priworst(mesh,sol); + +// #warning A ENLEVER +// for(it=1 ; it<=mesh->ne ; it++) { +// pt = &mesh->tetra[it]; +// if(pt->qual < declic) continue; +// pt->ref = ALPHAD*pt->qual; +// } + + return(1); +} + + diff --git a/contrib/mmg3d/build/sources/opttyp.c b/contrib/mmg3d/build/sources/opttyp.c new file mode 100644 index 0000000000..f1c9a5e138 --- /dev/null +++ b/contrib/mmg3d/build/sources/opttyp.c @@ -0,0 +1,821 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define OCRIT 0.99 +#undef QDEGRAD +#define QDEGRAD 2. + +int MMG_colpoi2(pMesh mesh,pSol sol,int iel,int ia,int ib,double coef); + +/* optimize mesh quality based on element type */ +int MMG_opttyp(pMesh mesh,pSol sol,double declic,int *alert) { + pTetra pt,pt1; + pPoint pa,pb; + List list; + pQueue queue; + double crit; + double len,*ca,*cb,*ma,*mb; + int *adja,i,k,l,iar,ia,ib,iel,iadr,ier,item[2],nd,base,ityp,np; + int npeau,cs[10],ds[10],dsb[3],lon,sombdry,dpeau; + int ipa,ipb,iarmin,iarmax,ndd,nbt,j; +double LLONG2; + + /*classification des mauvais : 0 si pas sur la peau*/ + /* 1 si au moins une face de peau */ + /* 2 si au moins une arete sur la peau */ + if(mesh->info.imprim < -5 ) { + puts(" "); + + nd = 0; + memset(cs,0,10*sizeof(int)); + memset(ds,0,10*sizeof(int)); + nbt = 0; + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; +//if(k== 40117) printf("tetra %d %e : %d %d %d %d\n",k,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + if(!pt->v[0] || pt->qual < declic) continue; + nbt++; +//if(k== 40117) printf("tetra %d %e : %d %d %d %d\n",k,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + for(i=0 ; i<4 ; i++) { + if(!adja[i])break; + } + if(i==4) { + for(i = 0 ; i<6 ; i++) + if(!MMG_coquil(mesh,k,i,&list)) break; + + if ( i==6 ) cs[0]++; + else cs[2]++; + } else cs[1]++; + } + + printf(" tetra interne = %5d / %5d %6.2f %%\n",cs[0],nbt,100.0*cs[0]/nbt); + printf(" tetra face peau = %5d / %5d %6.2f %%\n",cs[1],nbt,100.0*cs[1]/nbt); + printf(" tetra arete peau = %5d / %5d %6.2f %%\n",cs[2],nbt,100.0*cs[2]/nbt); + + printf("\n"); + + } + + + /*traitement des mauvais*/ + base = mesh->flag; + ier = 0; + queue = MMG_kiuini(mesh,mesh->nemax,declic,base - 1); + assert(queue); + + memset(cs,0,10*sizeof(int)); + memset(ds,0,10*sizeof(int)); + memset(dsb,0,3*sizeof(int)); + nd = 0; + + if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) { + fprintf(stdout," ## MEMORY ALLOCATION PROBLEM MMG_OPTTYP.\n"); + MMG_kiufree(queue); + return(0); + } + + np = 0; + do { + k = MMG_kiupop(queue); + if ( !k ) break; + np++; + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->qual < declic ) continue; + else if ( pt->flag != base - 1 ) continue; + + LLONG2 = 0.1; + + crit = pt->qual * OCRIT; + ityp = MMG_typelt(mesh,k,item); +cs[ityp]++; +//if(k==175494) printf("tetra %d (%d) %e : %d %d %d %d\n",k,ityp,pt->qual*ALPHAD,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + iadr = 4*(k-1) + 1; + adja = &mesh->adja[iadr]; + /*optim bdry tetra*/ + npeau = 0; + for(i=0 ; i<4 ; i++) { + if(!adja[i])npeau++; + } + + if(npeau>1 && !mesh->info.noswap) { + if(mesh->info.imprim<-4) printf("%d faces de peau!!!! %d (typ %d) %e\n",npeau,k,ityp,pt->qual * ALPHAD); + dsb[0]++; + if(MMG_opt2peau(mesh,sol,queue,k,declic)){ + nd++; + continue; + } + } + if(npeau) { + dpeau = MMG_optbdry(mesh,sol,k); + dsb[dpeau]++; + if(dpeau) { + nd++; + ds[ityp]++; + continue; + } + } + if(mesh->info.noswap) continue; + switch(ityp) { + case 1: /* sliver */ + iar = item[0]; + lon = MMG_coquil(mesh,k,iar,&list); + if ( lon > 2 ) { + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + /*impossible de dégrader à cause des swap 4-4*/ + crit *= OCRIT; + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if ( ier == 0 && !mesh->info.noinsert) { + if ( MMG_voltet(mesh,k) < 5.e-9 ) { + crit *= 2.; + crit = M_MIN(crit,8e+8); + } + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(len > LLONG2) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + + if ( ier ) { + pt1 = &mesh->tetra[mesh->point[ier].tmp]; + for(j=0 ; j<4 ; j++) { + if(pt1->v[j] == ier) break; + } + assert(j<4); + ier = MMG_movevertex(mesh,sol,mesh->point[ier].tmp,j); + if ( ier==1 ) { + } else { + ier = 1; + } + } + } + if ( ier > 0 ) { + nd++; + ds[1]++; + break; + } + else if ( ier < 0 ) { + *alert = 1; + break; + } + } + for(i=0 ; i<6 ; i++) { + if(i==item[0]) continue; + lon = MMG_coquil(mesh,k,i,&list); + if ( lon > 2 ) { + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + + if ( ier == 0 && !mesh->info.noinsert) { + /*if ( MMG_voltet(mesh,k) < 5.e-9 ) { //degrade trop les maillages!!! + crit *= 2.; + crit = M_MIN(crit,8e+8); + } */ + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(len > LLONG2) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + + if ( ier ) { + pt1 = &mesh->tetra[mesh->point[ier].tmp]; + for(j=0 ; j<4 ; j++) { + if(pt1->v[j] == ier) break; + } + assert(j<4); + ier = MMG_movevertex(mesh,sol,mesh->point[ier].tmp,j); + if ( ier==1 ) { + } else { + ier = 1; + } + } /*end if ier for movevertex*/ + } /*end if ier == 0 */ + + if ( ier > 0 ) { + nd++; + ds[1]++; + break; + } + else if ( ier < 0 ) + *alert = 1; + } /*end if lon==2*/ + } /*end for i*/ + if(i<6) break; + /*move vertex*/ + for(i=0 ; i<4 ; i++) { + if(MMG_movevertex(mesh,sol,k,i)) { + nd++; + ds[ityp]++; + break; + } + } + break; + + case 2: /* chapeau */ + /*on essaie de decoller le point de l'arete*/ + iar = item[0]; + if((sol->offset!=1) && MMG_movevertex(mesh,sol,k,iar)) { + nd++; + ds[ityp]++; + } else { + for(i=0 ; i<4 ; i++) { + if(iar==i) continue; + if((sol->offset!=1) && MMG_movevertex(mesh,sol,k,i)) { + nd++; + ds[ityp]++; + break; + } + } + } + break; + + case 3: /* aileron */ + iar = item[1]; + ier = MMG_simu23(mesh,sol,k,iar,crit); + if ( ier > 0 ) { + MMG_swap23(mesh,sol,queue,k,iar,crit); + nd++; + ds[ityp]++; + break; + } + else if ( ier < 0 ) { + *alert = 1; + break; + } + + iar = item[0]; + lon = MMG_coquil(mesh,k,iar,&list); +//if(!lon) printf("arete de bord!!!!!!!!!!!!!\n"); + if ( lon > 2 ) { + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if ( ier == 0 && !mesh->info.noinsert) { + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(len > LLONG2) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + + } + if ( ier > 0 ) { + nd++; + ds[3]++; + } + else if ( ier < 0 ) + *alert = 1; + } + + if(ier) break; + +// /*try collapse one edge*/ +// iar = item[0]; +// for(i=0 ; i<6 ; i++) { +// ia = MMG_iare[i][0]; +// ib = MMG_iare[i][1]; +// ipa = pt->v[ia]; +// ipb = pt->v[ib]; +// if(MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD)) { +// MMG_delPt(mesh,ipb); +// //printf("1 : on a reussi a supprimer le tetra mauvais \n"); +// break; +// } else if(MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD)) { +// MMG_delPt(mesh,ipa); +// //printf("2 : on a reussi a supprimer le tetra mauvais\n"); +// break; +// } +// +// } + + /*move vertex*/ + for(i=0 ; i<4 ; i++) { + if(MMG_movevertex(mesh,sol,k,i)) { + nd++; + ds[ityp]++; + break; + } + } + + break; + + case 4: /* berlingot */ + iar = item[0]; + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( !mesh->info.noinsert && !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) { + nd++; + MMG_delPt(mesh,ipb); + ds[ityp]++; + break; + } + else if( !mesh->info.noinsert && !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) { + nd++; + MMG_delPt(mesh,ipa); + ds[ityp]++; + break; + } + if( (sol->offset!=1) && !(pb->tag & M_BDRY)) { + if(MMG_movevertex(mesh,sol,k,ib)) { + nd++; + ds[ityp]++; + break; + } + } + if( (sol->offset!=1) && !(pa->tag & M_BDRY)) { + if(MMG_movevertex(mesh,sol,k,ia)) { + nd++; + ds[ityp]++; + break; + } + } + + break; + + case 5: /* 0 good face: split largest edge + node move */ + break; + + case 6: /* O good face: move away closest vertices */ + /*collapse item[0]*/ + ier = 0; + iar = item[0]; + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + if ( (MMG_length(ca,cb,ma,mb) < LSHORT) ) { + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( !mesh->info.noinsert && !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) { + ier = 2; + nd++; + MMG_delPt(mesh,ipb); + ds[ityp]++; + break; + } + else if( !mesh->info.noinsert && !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) { + ier = 2; + nd++; + MMG_delPt(mesh,ipa); + ds[ityp]++; + break; + } + } + + /*split item[1]*/ + iar = item[1]; + lon = MMG_coquil(mesh,k,iar,&list); + if ( lon <= 2 ) break; + + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if ( ier == 0 && !mesh->info.noinsert) { + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(len > LLONG2) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + } + if ( ier > 0 ) { + nd++; + ds[ityp]++; + break; + } + else if ( ier < 0 ) { + *alert = 1; + break; + } + break; + + case 7: + /*collapse d'une des 2 petites aretes*/ + ier = 0; + iarmin = item[0]; + iarmax = item[1]; + ia = MMG_iare[iarmin][0]; + ib = MMG_iare[iarmin][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + i = 6; + if(!mesh->info.noinsert && (MMG_length(ca,cb,ma,mb) < LSHORT)) { + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) { + ier = 2; + nd++; + MMG_delPt(mesh,ipb); + ds[ityp]++; + i = 0; + break; + } + else if( !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) { + ier = 2; + nd++; + MMG_delPt(mesh,ipa); + ds[ityp]++; + i = 0; + break; + } + } + if(ier) break; + + lon = MMG_coquil(mesh,k,iarmax,&list); + if ( lon <= 2 ) break; + if (!mesh->info.noinsert) { + lon = MMG_coquil(mesh,k,iarmax,&list); + if ( lon <= 2 ) break; + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + + ia = MMG_iare[iarmax][0]; + ib = MMG_iare[iarmax][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(len > LLONG2) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + + if ( ier > 0 ) { + nd++; + ds[ityp]++; + break; + } + } + + /*boucle sur les autres aretes != de iarmax et de iarmin*/ + for(i=0 ; i<6 ; i++) { + if(i==iarmin) continue; + if(i==iarmax) continue; + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + if(!mesh->info.noinsert && (len < LSHORT)) { + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + if ( !(pb->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ia,ib,QDEGRAD) ) { + ier = 3; + nd++; + MMG_delPt(mesh,ipb); + ds[ityp]++; + break; + } + else if( !(pa->tag & M_BDRY) && MMG_colpoi2(mesh,sol,k,ib,ia,QDEGRAD) ) { + ier = 3; + nd++; + MMG_delPt(mesh,ipa); + ds[ityp]++; + break; + } + } else if(!mesh->info.noinsert && (len > LLONG)) { + lon = MMG_coquil(mesh,k,i,&list); + if ( lon <= 2 ) break; + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + if (!mesh->info.noinsert) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + if ( ier > 0 ) { + nd++; + ds[ityp]++; + break; + } + } + } + + if(i<6) break; + if(ier) break; + /*MMG_swap arete*/ + for(i=0 ; i<6 ; i++) { + lon = MMG_coquil(mesh,k,i,&list); + if ( lon > 2 ) { + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + crit *= OCRIT; + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if(ier) { + nd++; + ds[ityp]++; + break; + } + } + } + + break; + default: +/* + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + if ( adj && pt->ref == mesh->tetra[adj].ref ) { + lon = MMG_coquil(mesh,k,i,list); + if ( MMG_swapar(mesh,sol,queue,k,i,list,lon,declic) ) { + nsw++; +ds[ityp]++; + break; + } + } + } +*/ + break; + } + + } + while ( k && *alert == 0 ); + + if(mesh->info.imprim<0) { + + for (k=0; k<=7; k++) + if ( cs[k] ) + printf(" optim [%d] = %5d %5d %6.2f %%\n",k,cs[k],ds[k],100.0*ds[k]/cs[k]); + + sombdry = dsb[0]+dsb[1]+dsb[2]; + for (k=1; k<=2; k++) + if ( dsb[k] ) + printf("\n optim bdry [%d] = %5d %5d %6.2f %%\n",k,dsb[k],sombdry,100.0*dsb[k]/sombdry); + + printf(" PROP %d TREATED %d\n",np,ds[0]+ds[1]+ds[2]+ds[3]+ds[4]+ds[5]+ds[6]+ds[7]); + + } + + M_free(list.hedg.item); + MMG_kiufree(queue); + + if (!mesh->info.noswap) { + base = -1; + *alert = 0; + ndd = MMG_cendel(mesh,sol,declic,base); + if ( mesh->info.imprim < 0 && ndd > 0 ) + fprintf(stdout," %7d SWAPPED\n",ndd); + else if ( ndd < 0 ) + *alert = 1; + } + + + + /* base = -1; + ier = 0; + queue = MMG_kiuini(mesh,mesh->nemax,declic,base); + assert(queue); + + do { + k = MMG_kiupop(queue); + if ( !k ) break; + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->qual < declic ) continue; + + crit = M_MIN(2.*pt->qual,8e+8); + + for (i=0; i<4; i++) { + if(MMG_simu23(mesh,sol,k,i,crit)) { + printf("je swap\n"); + MMG_swap23(mesh,sol,queue,k,i,1e+9); + break; + } + } + + } + while ( k && *alert == 0 ); + MMG_kiufree(queue);*/ + + + return(nd); +} + + +/* insert point in bad tetra */ +int MMG_pretreat(pMesh mesh,pSol sol,double declic,int *alert) { + pTetra pt,pt1; + List list; + pQueue queue; + double crit; + double len,*ca,*cb,*ma,*mb; + int i,k,l,ia,ib,iel,ier,nd,base,wqual; + int lon,iadr,ipa,ipb; + + wqual = 30. / ALPHAD; + + /*queue*/ + base = -1; + queue = MMG_kiuini(mesh,mesh->nemax,declic,base); + assert(queue); + + nd = 0; + + if ( !MMG_zaldy4(&list.hedg,3*LONMAX) ) { + fprintf(stdout," ## MEMORY ALLOCATION PROBLEM MMG_OPTTYP.\n"); + MMG_kiufree(queue); + return(0); + } + + do { + k = MMG_kiupop(queue); + if ( !k ) break; + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + else if ( pt->qual < declic ) continue; + + crit = pt->qual * OCRIT; + + for(i=0 ; i<6 ; i++) { + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + len = MMG_length(ca,cb,ma,mb); + + if(!mesh->info.noinsert && (len > LLONG)) { + lon = MMG_coquil(mesh,k,i,&list); + if ( lon <= 2 ) break; + crit = pt->qual; + for (l=2; l<=lon; l++) { + iel = list.tetra[l] / 6; + pt1 = &mesh->tetra[iel]; + if ( pt1->qual > crit ) crit = pt1->qual; + } + /*if(crit > wqual) { + crit *= 2.; + } else { + crit *= 1.05; + } */ + crit = M_MIN(crit,8.e+8); + ier = 0; + if (!mesh->info.noinsert) + ier = MMG_spledg(mesh,sol,queue,&list,lon,crit,declic); + if ( ier > 0 ) { + nd++; + break; + } + } + } + } + while ( k && *alert == 0 ); + + M_free(list.hedg.item); + MMG_kiufree(queue); + + return(nd); +} + diff --git a/contrib/mmg3d/build/sources/outqua.c b/contrib/mmg3d/build/sources/outqua.c new file mode 100644 index 0000000000..7d811c7d8c --- /dev/null +++ b/contrib/mmg3d/build/sources/outqua.c @@ -0,0 +1,318 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* print mesh quality histo */ +int MMG_outqua(pMesh mesh,pSol sol) { + pTetra pt; + double coef,rap4,rapl,rapmin,rapmax,rapavg,dcal; + int his10[11],his01[33],rapnum,iout; + int k,i,j,imax,iel,ir,nn,nex,ielreal,tmp; + + iout = 0; + + if(mesh->info.imprim < 0) MMG_priworst(mesh,sol); + + rapmin = 1.e20; + rapmax = -1.e20; + rapavg = 0.0; + rapnum = 0; + iel = 0; + ielreal = 0; + nn = 0; + + for (k=0; k<=32; k++) his01[k] = 0; + for (k=0; k<=10; k++) his10[k] = 0; + + coef = ALPHAD; + nex = 0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if( !pt->v[0] ) { + nex++; + continue; + } + nn++; + dcal = MMG_caltet(mesh,sol,k);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,k) : MMG_caltet_iso(mesh,sol,k); + rap4 = coef * dcal; + if(dcal == CALLIM) { + //printf("Wrong elt %d : %d %d %d %d (qual %e %e)\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3],rap4,MMG_voltet(mesh,k)); + tmp = pt->v[2]; + pt->v[2] = pt->v[3]; + pt->v[3] = tmp; + dcal = MMG_caltet(mesh,sol,k);//(sol->offset==6) ? MMG_caltet_ani(mesh,sol,k) : MMG_caltet_iso(mesh,sol,k); + rap4 = coef * dcal; + if(dcal == CALLIM) { + printf("Wrong elt %d : %d %d %d %d (qual %e (%e) %13.12f)\n",k,pt->v[0],pt->v[1],pt->v[2],pt->v[3],rap4,rap4/coef,MMG_voltet(mesh,k)); + printf("vextex 0 : %e %e %e\n",mesh->point[pt->v[0]].c[0],mesh->point[pt->v[0]].c[1],mesh->point[pt->v[0]].c[2]); + printf("vextex 1 : %e %e %e\n",mesh->point[pt->v[1]].c[0],mesh->point[pt->v[1]].c[1],mesh->point[pt->v[1]].c[2]); + printf("vextex 2 : %e %e %e\n",mesh->point[pt->v[2]].c[0],mesh->point[pt->v[2]].c[1],mesh->point[pt->v[2]].c[2]); + printf("vextex 3 : %e %e %e\n",mesh->point[pt->v[3]].c[0],mesh->point[pt->v[3]].c[1],mesh->point[pt->v[3]].c[2]); + //MMG_saveMesh(mesh,"titi.mesh"); + //exit(0); + iout += 1; + } + if(abs(mesh->info.imprim) > 5) printf("reorient tet %d\n",k); + //iout += 1; + } + //rap4 = M_MIN(rap4,1.0e9); + ir = (int)rap4; + if ( rap4 > rapmax ) { + rapmax = rap4; + iel = k; + ielreal = k - nex; + } + rapavg += rap4; + rapnum++; + + if ( rap4 > 1.0 && rap4 < 17e10 ) { + rapmin = M_MIN(rapmin,rap4); + if ( rap4 < 10.0 ) { + his10[ir] += 1; + his01[0] += 1; + } + else if ( rap4 < 17e10 ) { + rapl = M_MIN(log10(rap4),32.0); + his01[(int)rapl] += 1; + his01[0] += 1; + } + } + } + + /* print histo */ + fprintf(stdout,"\n -- MESH QUALITY %d \n",rapnum); + if ( (rapavg > 0) && (rapavg / rapnum < 100.0) ) + fprintf(stdout," AVERAGE QUALITY %12.4f\n",rapavg / rapnum); + fprintf(stdout," BEST ELEMENT QUALITY %12.4f\n",rapmin); + if ( rapmax < 1.e7 ) + fprintf(stdout," WORST ELEMENT QUALITY %12.4f\n",rapmax); + else + fprintf(stdout," WORST ELEMENT QUALITY %12.4E\n",rapmax); + pt = &mesh->tetra[iel]; + fprintf(stdout," WORST ELEMENT %d (%d) %d %d %d %d\n", + iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + + if ( abs(mesh->info.imprim) < 5 ) return(0); + + fprintf(stdout,"\n HISTOGRAMM\n"); + j = 0; + for (i=1; i<32; i++) + j += his01[i]; + + if(rapmax > 1e+9) + imax = 9; + else + imax = M_MIN((int)rapmax,9); + + for (i=M_MAX((int)rapmin,1); i<=imax; i++) { + fprintf(stdout," %5d < Q < %5d %7d %6.2f %%\n", + i,i+1,his10[i],100.*(his10[i]/(float)his01[0])); + } + + /* quality per interval */ + if (j != 0) { + fprintf(stdout,"\n"); + imax = (int)(M_MIN(3,log10(rapmax))); + + for (i=1; i<=imax; i++) { + fprintf(stdout," %5.0f < Q < %5.0f %7d %6.2f %%\n", + pow(10.,i),pow(10.,i+1),his01[i],100.*(his01[i]/(float)his01[0])); + } + for (i=4; i<=(int)log10(rapmax); i++) { + fprintf(stdout," 10**%2d < Q < 10**%2d %7d %6.2f %%\n", + i,i+1,his01[i],100.*(his01[i]/(float)his01[0])); + } + } + return(iout); +} + +double MMG_priworst(pMesh mesh, pSol sol) { + pTetra pt; + int k,nbad,nreal,nex; + double bad; + + /*worst quality*/ + bad = 1.; + nbad = 0; + nex = 0; + nreal = 0; + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) { + nex++; + continue; + } + if( pt->qual > bad) { + bad = pt->qual; + nbad = k - nex; + nreal = k; + } + } + + if(nreal) printf(" worst quality %d (%d): %e %e\n",nreal,nbad,bad*ALPHAD,ALPHAC*MMG_calte1(mesh,sol,nreal)); + + return((&mesh->tetra[nreal])->qual); +} +/* print mesh quality histo */ +int MMG_outquacubic(pMesh mesh,pSol sol) { + pTetra pt; + double rapmin,rapmax,rapavg,dcal,som; + int his10[11],his01[5],rapnum,iout; + int k,i,j,iel,ir,nn,nex,ielreal,hismin; + + iout = 0; + + rapmin = 0.; + rapmax = 1.; + rapavg = 0.0; + rapnum = 0; + iel = 0; + ielreal = 0; + nn = 0; + + for (k=0; k<=5; k++) his01[k] = 0; + for (k=0; k<=10; k++) his10[k] = 0; + + nex = 0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if( !pt->v[0] ) { + nex++; + continue; + } + nn++; + dcal = MMG_caltetcubic(mesh,sol,k); + if(dcal > 1) { + //printf("argggggg %d %e %e\n",k,dcal,MMG_caltet(mesh,sol,k)*ALPHAD); + dcal = 1.; + } + if(dcal == 0.) { + printf("Wrong elt %d (qual %e)\n",k,dcal); + iout += 1; + } + ir = (int)(dcal*10); + if ( dcal < rapmax ) { + rapmax = dcal; + iel = k; + ielreal = k - nex; + } + rapavg += dcal; + rapnum++; + + if ( dcal <= 1.0 && dcal >= 1e-12 ) { + rapmin = M_MAX(rapmin,dcal); + if ( dcal > 0.1 ) { + his10[ir] += 1; + his01[0] += 1; + } + else if ( dcal > 1e-12 ) { + if(dcal > 0.01) { + his01[1] += 1; + } else if (dcal > 0.001) { + his01[2] += 1; + } else if (dcal > 0.0001) { + his01[3] += 1; + } else + his01[4] += 1; + his01[0] += 1; + } + } + } + + /* print histo */ + fprintf(stdout,"\n -- MESH QUALITY (CUBIC) %d\n",rapnum); + if ( rapavg / rapnum > 0.1 ) + fprintf(stdout," AVERAGE QUALITY %12.4f\n",rapavg / rapnum); + fprintf(stdout," BEST ELEMENT QUALITY %12.4f\n",rapmin); + if ( rapmin > 1.e-6 ) + fprintf(stdout," WORST ELEMENT QUALITY %12.4f\n",rapmax); + else + fprintf(stdout," WORST ELEMENT QUALITY %12.4E\n",rapmax); + pt = &mesh->tetra[iel]; + fprintf(stdout," WORST ELEMENT %d (%d) %d %d %d %d\n", + iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + + if ( abs(mesh->info.imprim) < 5 ) return(0); + + fprintf(stdout,"\n HISTOGRAMM\n"); + j = 0; + for (i=1; i<4; i++) + j += his01[i]; + hismin = M_MIN((int)(rapmin*10),1); + som = 0; + if( hismin == 1) { + fprintf(stdout," 0.9 < Q < 1.0 %7d %6.2f %%\n", + his10[9]+his10[10],100.*((his10[9]+his10[10])/(float)his01[0])); + hismin = 9; + som += 100.*((his10[9]+his10[10])/(float)his01[0]); + } + for (i=hismin; i>M_MAX((int)(rapmax*10),1); i--) { + fprintf(stdout," 0.%d < Q < 0.%d %7d %6.2f %%\n", + i-1,i,his10[i-1],100.*(his10[i-1]/(float)his01[0])); + som += 100.*(his10[i-1]/(float)his01[0]); + } + + /* quality per interval */ + if (j != 0) { + fprintf(stdout,"\n"); + j -= his01[1]; + if(his01[1]!=0) + fprintf(stdout," 0.01 < Q < 0.1 %7d %6.2f %%\n", + his01[1],100.*(his01[1]/(float)his01[0])); + if(j!=0) + fprintf(stdout," 0.001 < Q < 0.01 %7d %6.2f %%\n", + his01[2],100.*(his01[1]/(float)his01[0])); + j -= his01[2]; + if(j!=0) + fprintf(stdout," 0.0001 < Q < 0.001 %7d %6.2f %%\n", + his01[3],100.*(his01[1]/(float)his01[0])); + j -= his01[3]; + if(j!=0) + fprintf(stdout," 0. < Q %7d %6.2f %%\n", + his01[4],100.*(his01[1]/(float)his01[0])); + } + return(iout); +} diff --git a/contrib/mmg3d/build/sources/pattern.c b/contrib/mmg3d/build/sources/pattern.c new file mode 100644 index 0000000000..d099405165 --- /dev/null +++ b/contrib/mmg3d/build/sources/pattern.c @@ -0,0 +1,2440 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + + +unsigned char MMG_arfa[3][4] = { {2,0,1,3}, {1,2,0,3}, {0,1,2,3} }; +extern int MMG_permar[10][4]; +extern int MMG_pointar[64][2]; +extern int ddebug; +//insert ip on ia-ib +int MMG_pattern1(pMesh mesh,pSol sol,pHedge hash,int jel) { + pTetra pt,pt1; + int iel,ia,ib,ic,id,ip,tabref[4],i; + if(ddebug) printf("on cut 1\n"); + + pt = &mesh->tetra[jel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 1) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + ip = MMG_edgePoint(hash,ia,ib); + assert(ip); + if(ddebug) printf("ia %d %d %d %d\n",ia,ib,ic,id); + pt->v[0] = ia; + pt->v[1] = ip; + pt->v[2] = ic; + pt->v[3] = id; + pt->qual = MMG_caltet(mesh,sol,jel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[1]; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + if(ddebug) printf("creationi %d : %d %d %d %d\n",jel,ia,ip,ic,id); + + iel = MMG_newElt(mesh); + pt1 = &mesh->tetra[iel]; + pt1->v[0] = ip; + pt1->v[1] = ib; + pt1->v[2] = ic; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + if(ddebug) printf("tabref %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]); + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + if(ddebug) printf("creationi %d : %d %d %d %d\n",iel,ip,ib,ic,id); + //if(ddebug) exit(1); + return(1); +} + +int MMG_pattern2(pMesh mesh,pSol sol,pHedge hash, int iel) { + pTetra pt,pt1; + int jel,ia,ib,ic,id,iad,ibc,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 12) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + ibc = MMG_edgePoint(hash,ib,ic); + assert(ibc>0); + + pt->v[0] = ibc; + pt->v[1] = ic; + pt->v[2] = iad; + pt->v[3] = id; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[1]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = -1; + + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ibc; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ibc; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + return(1); +} + +int MMG_pattern22(pMesh mesh,pSol sol,pHedge hash, int iel) { + pTetra pt,pt1; + int jel,ia,ib,ic,id,iab,ibd,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 17) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + iab = MMG_edgePoint(hash,ia,ib); + assert(iab>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + pt->v[0] = iab; + pt->v[1] = ib; + pt->v[2] = ic; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + //if(pt->qual==CALLIM) puts("ahhhhhhhhh1"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + + if ( ia > id ) { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iab; + pt1->v[1] = ibd; + pt1->v[2] = ic; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("bbahhhhhhhhh1"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = ic; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh11"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + } else { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = ic; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) printf("ahhhvhhhhhh11 %d %d %d %d\n",ia,iab,ib,ibd); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ic; + pt1->v[2] = id; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahvvhhhhhhhh11"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + + } + + return(1); +} + +int MMG_pattern3(pMesh mesh,pSol sol,pHedge hash,int iel) { + pTetra pt,pt1; + int ia,ib,ic,id,iad,iab,ibd,jel,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 21) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + iab = MMG_edgePoint(hash,ia,ib); + assert(iab>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + + pt->v[0] = iab; + pt->v[1] = ib; + pt->v[2] = ic; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ic; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iab; + pt1->v[1] = iad; + pt1->v[2] = ibd; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + return(1); + +} + +int MMG_pattern31(pMesh mesh,pSol sol,pHedge hash,int iel) { + pTetra pt,pt1; + int ia,ib,ic,id,iad,icd,ibd,jel,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + if(pt->tabedg != 52) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + icd = MMG_edgePoint(hash,ic,id); + assert(icd>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + + pt->v[0] = iad; + pt->v[1] = ibd; + pt->v[2] = icd; + pt->v[3] = id; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = tabref[1]; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = pt->ref; + + if ( (ia > ib) && (ib > ic) ) { + assert(ia > ic); + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = iad; + pt1->v[2] = ibd; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = pt->ref; + } + else if ( (ia > ib) && (ic > ib) && (ic > ia)) { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = icd; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ia; + pt1->v[2] = ib; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = icd; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = pt->ref; + } + else if ( (ia > ib) && (ic > ib) && (ia > ic)) { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = icd; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = pt->ref; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = pt->ref; + } + else if ( (ib > ia) && (ib > ic) && (ic > ia)) { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ia; + pt1->v[2] = ibd; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ia; + pt1->v[2] = ibd; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ibd; + pt1->v[2] = icd; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = pt->ref; + } + else if ( (ib > ia) && (ib > ic) && (ia > ic)) { + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ia; + pt1->v[2] = ibd; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ic; + pt1->v[2] = ibd; + pt1->v[3] = ia; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = pt->ref; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = pt->ref; + } + else if ( (ib > ia) && (ic > ib) ) { + assert(ic > ia); + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ic; + pt1->v[2] = ia; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = pt->ref; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ibd; + pt1->v[2] = icd; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = pt->ref; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = pt->ref; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = icd; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = pt->ref; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = pt->ref; + } + + return(1); + +} + +int MMG_pattern32(pMesh mesh,pSol sol,pHedge hash,int iel) { + pTetra pt,pt1; + int ia,ib,ic,id,iad,ibc,ibd,jel,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + if(pt->tabedg != 28) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + ibc = MMG_edgePoint(hash,ib,ic); + assert(ibc>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + + if ( (ia > ib) && (ic > id) ) { + pt->v[0] = iad; + pt->v[1] = ib; + pt->v[2] = ia; + pt->v[3] = ibc; + pt->qual = MMG_caltet(mesh,sol,iel); + //if(pt->qual==CALLIM) puts("ahhhhhhhhh1"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[3]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ibc; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("bahhhhhhhhh2"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ibc; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("bahhhhhhhhh3"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = iad; + pt1->v[2] = id; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("bahhhhhhhhh4"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ia; + pt1->v[2] = ibc; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("bahhhhhhhhh5"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = tabref[3]; + } + else if ( (ia > ib) && (id > ic) ) { + pt->v[0] = iad; + pt->v[1] = ib; + pt->v[2] = ia; + pt->v[3] = ibc; + pt->qual = MMG_caltet(mesh,sol,iel); + //if(pt->qual==CALLIM) puts("ahhhhhhhhh1"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[3]; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ibc; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh2"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ibc; + pt1->v[2] = iad; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh3"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = iad; + pt1->v[2] = id; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh4"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ia; + pt1->v[2] = ibc; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh5"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = tabref[3]; + } + else if ( (ib > ia) && (ic > id) ) { + pt->v[0] = ia; + pt->v[1] = iad; + pt->v[2] = ibc; + pt->v[3] = ic; + pt->qual = MMG_caltet(mesh,sol,iel); + // if(pt->qual==CALLIM) puts("ahhhhhhhhh6"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[3]; + pt->bdryref[2] = tabref[1]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh7"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ia; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh8"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh9"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = iad; + pt1->v[2] = ibd; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh10"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + } + else if ( (ib > ia) && (id > ic) ) { + pt->v[0] = iad; + pt->v[1] = ibd; + pt->v[2] = ia; + pt->v[3] = ic; + pt->qual = MMG_caltet(mesh,sol,iel); + //if(pt->qual==CALLIM) puts("ahhhhhhhhh11"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[1]; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh12"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = iad; + pt1->v[2] = ibd; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh13"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = ic; + pt1->v[2] = ia; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + //if(pt1->qual==CALLIM) puts("ahhhhhhhhh14"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[3]; + + } + + return(1); + +} + +int MMG_pattern33(pMesh mesh,pSol sol,pHedge hash,int iel) { + pTetra pt,pt1; + int ia,ib,ic,id,iad,iac,ibd,jel,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + if(pt->tabedg != 22) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + iac = MMG_edgePoint(hash,ia,ic); + assert(iac>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + + if ( (ia > ib) && (ic > id) ) { + pt->v[0] = ia; + pt->v[1] = ib; + pt->v[2] = iac; + pt->v[3] = iad; + pt->qual = MMG_caltet(mesh,sol,iel); + if(pt->qual==CALLIM) printf("tet 1\n"); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[1]; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ic; + pt1->v[2] = id; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("tet 2\n"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = ib; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("tet 3\n"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[0]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = iac; + pt1->v[2] = ibd; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("tet 4\n"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = iac; + pt1->v[2] = id; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("tet 5\n"); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + } + else if ( (ia > ib) && (id > ic) ) { + pt->v[0] = ia; + pt->v[1] = ib; + pt->v[2] = iac; + pt->v[3] = iad; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[1]; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = ib; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[0]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = iac; + pt1->v[2] = ibd; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = iac; + pt1->v[2] = ic; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ic; + pt1->v[2] = id; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + } + else if ( (ib > ia) && (ic > id) ) { + pt->v[0] = iac; + pt->v[1] = ic; + pt->v[2] = id; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = ib; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[0]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = iac; + pt1->v[2] = id; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ia; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ibd; + pt1->v[2] = ia; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[3]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + } + else if ( (ib > ia) && (id > ic) ) { + pt->v[0] = ibd; + pt->v[1] = ic; + pt->v[2] = ib; + pt->v[3] = iac; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[3]; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[0]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ia; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ibd; + pt1->v[2] = ia; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[3]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = iad; + pt1->v[2] = ic; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + } + + return(1); + +} + +int MMG_pattern4(pMesh mesh,pSol sol,pHedge hash, int iel) { + pTetra pt,pt1; + int jel,ia,ib,ic,id,iab,ibd,ibc,iad,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 29) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + iab = MMG_edgePoint(hash,ia,ib); + assert(iab>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + ibc = MMG_edgePoint(hash,ib,ic); + assert(ibc>0); + + if ( ( ic > id ) && ( ia > ic ) ) { + pt->v[0] = iab; + pt->v[1] = ibc; + pt->v[2] = ic; + pt->v[3] = iad; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = id; + pt1->v[1] = ibd; + pt1->v[2] = iad; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = iab; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = iab; + pt1->v[2] = ibc; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ia; + pt1->v[2] = ic; + pt1->v[3] = iab; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ic; + pt1->v[2] = id; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + } + else if ( ( ic > id ) && ( ic > ia ) ) { + pt->v[0] = iad; + pt->v[1] = ia; + pt->v[2] = ibc; + pt->v[3] = iab; + pt->qual = MMG_caltet(mesh,sol,iel); + if(pt->qual==CALLIM) printf("biel %d\n",iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[3]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = iab; + pt1->v[2] = ibc; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("ciel %d\n",iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = iab; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("diel %d\n",iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iad; + pt1->v[2] = ibc; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("eiel %d\n",iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[3]; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = id; + pt1->v[1] = ibd; + pt1->v[2] = iad; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("fiel %d\n",iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ic; + pt1->v[2] = id; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + if(pt1->qual==CALLIM) printf("giel %d\n",iel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + } + else if ( ia > ic ) { + assert(id > ic); + pt->v[0] = iab; + pt->v[1] = ibc; + pt->v[2] = ic; + pt->v[3] = iad; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ibc; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = iab; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iab; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = ic; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + } + else { + assert(id > ic); + assert(ic > ia); + pt->v[0] = ibd; + pt->v[1] = ic; + pt->v[2] = ibc; + pt->v[3] = iad; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[0]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ibc; + pt1->v[2] = ic; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = ibc; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iab; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iad; + pt1->v[1] = ibd; + pt1->v[2] = iab; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[2]; + } + + return(1); +} + + +int MMG_pattern41(pMesh mesh,pSol sol,pHedge hash, int iel) { + pTetra pt,pt1; + int jel,ia,ib,ic,id,iab,icd,iac,ibd,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + if(pt->tabedg != 51) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + iab = MMG_edgePoint(hash,ia,ib); + assert(iab>0); + icd = MMG_edgePoint(hash,ic,id); + assert(icd>0); + iac = MMG_edgePoint(hash,ia,ic); + assert(iac>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + + if ( ( ib > ic ) && ( ia > id ) ) { /*tetrap43.mesh*/ + pt->v[0] = id; + pt->v[1] = iab; + pt->v[2] = iac; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = id; + pt1->v[1] = ia; + pt1->v[2] = iac; + pt1->v[3] = iab; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ic; + pt1->v[2] = ibd; + pt1->v[3] = iab; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = icd; + pt1->v[2] = iac; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ib; + pt1->v[2] = iab; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = iac; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + } + else if ( ( ib > ic ) && ( id > ia ) ) { /*tetra45.mesh*/ + pt->v[0] = ia; + pt->v[1] = id; + pt->v[2] = ibd; + pt->v[3] = icd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[1]; + pt->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = icd; + pt1->v[1] = iac; + pt1->v[2] = ibd; + pt1->v[3] = ia; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ic; + pt1->v[2] = ibd; + pt1->v[3] = iab; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = iab; + pt1->v[2] = iac; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ib; + pt1->v[2] = iab; + pt1->v[3] = ic; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = tabref[2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = ic; + pt1->v[2] = iac; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + } + else if ( ( ic > ib ) && ( ia > id ) ) { /*tetrap52.mesh*/ + pt->v[0] = ib; + pt->v[1] = icd; + pt->v[2] = iab; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[2]; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = iab; + pt1->v[2] = icd; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = id; + pt1->v[1] = iab; + pt1->v[2] = icd; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ia; + pt1->v[2] = iab; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = icd; + pt1->v[2] = iab; + pt1->v[3] = ib; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[3]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ib; + pt1->v[2] = icd; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = tabref[0]; + } + else { /*tetrap54.mesh*/ + assert(( ic > ib ) && ( id > ia ) ); + pt->v[0] = ib; + pt->v[1] = icd; + pt->v[2] = iab; + pt->v[3] = ibd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = tabref[2]; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = icd; + pt1->v[1] = ia; + pt1->v[2] = iac; + pt1->v[3] = iab; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[3]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = icd; + pt1->v[2] = iab; + pt1->v[3] = ia; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = id; + pt1->v[1] = ia; + pt1->v[2] = icd; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[0]; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[1]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = iab; + pt1->v[2] = ib; + pt1->v[3] = icd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = tabref[3]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ic; + pt1->v[1] = ib; + pt1->v[2] = icd; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = tabref[0]; + } + + return(1); +} + +int MMG_pattern5(pMesh mesh,pSol sol,pHedge hash, int iel) { + pTetra pt,pt1; + int jel,ia,ib,ic,id,iac,icd,ibd,ibc,iad,i,tabref[4]; + + pt = &mesh->tetra[iel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt->bdryref[MMG_permar[MMG_pointar[pt->tabedg][0]][i]]; + + if(pt->tabedg != 62) { + ia = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][0]]; + ib = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][1]]; + ic = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][2]]; + id = pt->v[MMG_permar[MMG_pointar[pt->tabedg][0]][3]]; + } else { + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + } + iac = MMG_edgePoint(hash,ia,ic); + assert(iac>0); + ibc = MMG_edgePoint(hash,ib,ic); + assert(ibc>0); + ibd = MMG_edgePoint(hash,ib,id); + assert(ibd>0); + icd = MMG_edgePoint(hash,ic,id); + assert(icd>0); + iad = MMG_edgePoint(hash,ia,id); + assert(iad>0); + if(0 && (iel==8778 || iel==6508 )) ddebug = 1; + if(iel==6512) ddebug=1; + if(ddebug) printf("tet %d : %d %d %d %d\n",iel,ia,ib,ic,id); + if(ddebug) printf("cas %d : %d %d %d %d\n",pt->tabedg,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + if(ddebug) printf("bdyref %d %d %d %d\n",pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + if(ddebug) printf("tabref %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]); + if ( ( ia > ib ) ) { /*tetra_p51.mesh*/ + pt->v[0] = ibc; + pt->v[1] = ic; + pt->v[2] = iac; + pt->v[3] = icd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[1]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = tabref[3]; + if(ddebug) printf("1 : on change %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = icd; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = icd; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = icd; + pt1->v[2] = iac; + pt1->v[3] = iad; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ibc; + pt1->v[2] = iad; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ib; + pt1->v[1] = ia; + pt1->v[2] = iad; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1;//tabref[2]; + pt1->bdryref[2] = tabref[3];//tabref[3]; + pt1->bdryref[3] = tabref[2];//-1; + if(ddebug) printf("--on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibc; + pt1->v[1] = ib; + pt1->v[2] = iad; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[3]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + } + else { /*tetra_p54.mesh*/ + pt->v[0] = ibc; + pt->v[1] = ic; + pt->v[2] = iac; + pt->v[3] = icd; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->tabedg = 0; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[1]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = tabref[3]; + if(ddebug) printf("2 : on change %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = icd; + pt1->v[2] = iad; + pt1->v[3] = id; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = tabref[2]; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ibd; + pt1->v[2] = iad; + pt1->v[3] = ia; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = tabref[1]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = iac; + pt1->v[1] = ia; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1;//tabref[3]; + pt1->bdryref[3] = tabref[3];//-1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = ibc; + pt1->v[3] = ibd; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[0]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[2]; + pt1->bdryref[3] = tabref[3]; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ibd; + pt1->v[1] = iad; + pt1->v[2] = icd; + pt1->v[3] = iac; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[1]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = icd; + pt1->v[1] = ibd; + pt1->v[2] = iac; + pt1->v[3] = ibc; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->ref = pt->ref; + pt1->flag = mesh->flag; + pt1->bdryref[0] = -1; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[0]; + pt1->bdryref[3] = -1; + if(ddebug) printf("on cree %d : %d %d %d %d\n",jel,pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + } + ddebug = 0; + return(1); +} + +//insert ip02 on ip0ip2 etc... + +/*create 8 tets +ip02 ip0 ip01 ip03 +ip01 ip1 ip12 ip13 +ip12 ip2 ip02 ip23 +ip23 ip3 ip03 ip13 +ip02 i12 ip03 ip01 +ip01 ip03 ip13 ip12 +ip12 ip03 ip23 ip02 +ip23 ip12 ip13 ip03 +*/ +int MMG_pattern6(pMesh mesh,pSol sol,int jel,int *ipa) { + pTetra pt,pt1; + int iel,ip0,ip1,ip2,ip3,i,tabref[4]; + + pt1 = &mesh->tetra[jel]; + for (i=0 ; i<4 ; i++) + tabref[i] = pt1->bdryref[i]; + + + ip0 = pt1->v[0]; + ip1 = pt1->v[1]; + ip2 = pt1->v[2]; + ip3 = pt1->v[3]; + ddebug = 0; + if(ddebug) printf("tet %d : %d %d %d %d\n",jel,ip0,ip1,ip2,ip3); + if(ddebug) printf("bdyref %d %d %d %d\n",pt1->bdryref[0],pt1->bdryref[1],pt1->bdryref[2],pt1->bdryref[3]); + if(ddebug) printf("tabref %d %d %d %d\n",tabref[0],tabref[1],tabref[2],tabref[3]); + ddebug = 0; + + pt1->v[0] = ipa[1]; + pt1->v[1] = ip0; + pt1->v[2] = ipa[0]; + pt1->v[3] = ipa[2]; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->tabedg = 0; + pt1->flag = mesh->flag; + pt1->bdryref[0] = tabref[2]; + pt1->bdryref[1] = -1; + pt1->bdryref[2] = tabref[1]; + pt1->bdryref[3] = tabref[3]; + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[0]; + pt->v[1] = ip1; + pt->v[2] = ipa[3]; + pt->v[3] = ipa[4]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[0]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[2]; + pt->bdryref[3] = tabref[3]; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[3]; + pt->v[1] = ip2; + pt->v[2] = ipa[1]; + pt->v[3] = ipa[5]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[1]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = tabref[3]; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[5]; + pt->v[1] = ip3; + pt->v[2] = ipa[2]; + pt->v[3] = ipa[4]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[2]; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[0]; + pt->bdryref[3] = tabref[1]; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[1]; + pt->v[1] = ipa[3]; + pt->v[2] = ipa[2]; + pt->v[3] = ipa[0]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = tabref[3]; + pt->bdryref[3] = -1; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[0]; + pt->v[1] = ipa[2]; + pt->v[2] = ipa[4]; + pt->v[3] = ipa[3]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[2]; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[3]; + pt->v[1] = ipa[2]; + pt->v[2] = ipa[5]; + pt->v[3] = ipa[1]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = tabref[1]; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = -1; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + + iel = MMG_newElt(mesh); + pt = &mesh->tetra[iel]; + pt->v[0] = ipa[5]; + pt->v[1] = ipa[3]; + pt->v[2] = ipa[4]; + pt->v[3] = ipa[2]; + pt->qual = MMG_caltet(mesh,sol,iel); + pt->ref = pt1->ref; + pt->flag = mesh->flag; + pt->bdryref[0] = -1; + pt->bdryref[1] = -1; + pt->bdryref[2] = -1; + pt->bdryref[3] = tabref[0]; + // printf("on cree %d : %d %d %d %d\n",iel,pt->bdryref[0],pt->bdryref[1],pt->bdryref[2],pt->bdryref[3]); + //printf("on cut 6\n"); + //exit(1); + return(1); +} + diff --git a/contrib/mmg3d/build/sources/quality.c b/contrib/mmg3d/build/sources/quality.c new file mode 100644 index 0000000000..7a78991ac0 --- /dev/null +++ b/contrib/mmg3d/build/sources/quality.c @@ -0,0 +1,1745 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + + +double MMG_rao(pMesh mesh,int k,int inm); +double MMG_caltetrao(pMesh mesh,pSol sol,int iel) { + return(MMG_rao(mesh,iel,0)); +} + +/* compute tetra volume */ +double MMG_voltet(pMesh mesh,int iel) { + pTetra pt; + pPoint p1,p2,p3,p4; + double ax,ay,az,bx,by,bz,vol,len; + int s1,s2,s3,s4; + + pt = &mesh->tetra[iel]; + s1 = pt->v[0]; + s2 = pt->v[1]; + s3 = pt->v[2]; + s4 = pt->v[3]; + + /* sort tetra vertices */ + if ( pt->v[0] < pt->v[1] ) { + if ( pt->v[0] < pt->v[2] ) { + s3 = pt->v[2]; + if ( pt->v[0] < pt->v[3] ) { + s1 = pt->v[0]; + s2 = pt->v[1]; + s4 = pt->v[3]; + } + else { + s1 = pt->v[3]; + s2 = pt->v[0]; + s4 = pt->v[1]; + } + } + else { + s2 = pt->v[0]; + if ( pt->v[2] < pt->v[3] ) { + s1 = pt->v[2]; + s3 = pt->v[1]; + s4 = pt->v[3]; + } + else { + s1 = pt->v[3]; + s3 = pt->v[2]; + s4 = pt->v[1]; + } + } + } + else { + if ( pt->v[1] < pt->v[2] ) { + if ( pt->v[1] < pt->v[3] ) { + s1 = pt->v[1]; + s2 = pt->v[2]; + s3 = pt->v[0]; + s4 = pt->v[3]; + } + else { + s1 = pt->v[3]; + s2 = pt->v[0]; + s3 = pt->v[2]; + s4 = pt->v[1]; + } + } + else { + s2 = pt->v[0]; + if ( pt->v[2] < pt->v[3] ) { + s1 = pt->v[2]; + s3 = pt->v[1]; + s4 = pt->v[3]; + } + else { + s1 = pt->v[3]; + s3 = pt->v[2]; + s4 = pt->v[1]; + } + } + } + + p1 = &mesh->point[s1]; + p2 = &mesh->point[s4]; + p3 = &mesh->point[s2]; + p4 = &mesh->point[s3]; + if ( s2 < s3 ) { + if ( s2 < s4 ) { + p2 = &mesh->point[s2]; + p3 = &mesh->point[s3]; + p4 = &mesh->point[s4]; + } + } + else if ( s3 < s4 ) { + p2 = &mesh->point[s3]; + p3 = &mesh->point[s4]; + p4 = &mesh->point[s2]; + } + + /* compute volume */ + ax = p3->c[0] - p1->c[0]; + ay = p3->c[1] - p1->c[1]; + az = p3->c[2] - p1->c[2]; + + bx = p4->c[0] - p1->c[0]; + by = p4->c[1] - p1->c[1]; + bz = p4->c[2] - p1->c[2]; + //printf("a %e %e %e \n",(ay*bz - az*by),(az*bx - ax*bz),(ax*by - ay*bx)); + vol = (p2->c[0]-p1->c[0]) * (ay*bz - az*by) \ + + (p2->c[1]-p1->c[1]) * (az*bx - ax*bz) \ + + (p2->c[2]-p1->c[2]) * (ax*by - ay*bx); + //printf("%e %e %e\n",(p2->c[0]-p1->c[0]),(p2->c[1]-p1->c[1]),(p2->c[2]-p1->c[2])); + //printf("vol1 %e %e %e\n",(p2->c[0]-p1->c[0]) * (ay*bz - az*by),(p2->c[1]-p1->c[1]) * (az*bx - ax*bz), + // (p2->c[2]-p1->c[2]) * (ax*by - ay*bx)); + len = ax*ax+ay*ay+az*az; + len += bx*bx+by*by+bz*bz; + len += (p2->c[0]-p1->c[0])*(p2->c[0]-p1->c[0])+(p2->c[1]-p1->c[1])*(p2->c[1]-p1->c[1]) + + (p2->c[2]-p1->c[2])*(p2->c[2]-p1->c[2]); + len += (p2->c[0]-p3->c[0])*(p2->c[0]-p3->c[0])+(p2->c[1]-p3->c[1])*(p2->c[1]-p3->c[1]) + + (p2->c[2]-p3->c[2])*(p2->c[2]-p3->c[2]); + len += (p2->c[0]-p4->c[0])*(p2->c[0]-p4->c[0])+(p2->c[1]-p4->c[1])*(p2->c[1]-p4->c[1]) + + (p2->c[2]-p4->c[2])*(p2->c[2]-p4->c[2]); + len += (p3->c[0]-p4->c[0])*(p3->c[0]-p4->c[0])+(p3->c[1]-p4->c[1])*(p3->c[1]-p4->c[1]) + + (p3->c[2]-p4->c[2])*(p3->c[2]-p4->c[2]); + len /= 6.; + len = sqrt(len); + len = len*len*len; + //printf("vol %e %e\n",vol,len); + vol /= len; + return(vol); +} + + +/* quick volume check */ +double MMG_quickvol(double *c1,double *c2,double *c3,double *c4) { + double ax,ay,az,bx,by,bz,vol; + + ax = c3[0] - c1[0]; + ay = c3[1] - c1[1]; + az = c3[2] - c1[2]; + + bx = c4[0] - c1[0]; + by = c4[1] - c1[1]; + bz = c4[2] - c1[2]; + + vol = (c2[0]-c1[0]) * (ay*bz - az*by) \ + + (c2[1]-c1[1]) * (az*bx - ax*bz) \ + + (c2[2]-c1[2]) * (ax*by - ay*bx); + + return(vol); +} + + +/* compute tetra quality aniso */ +double MMG_caltet_ani(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz; + double h1,h2,h3,h4,h5,h6,det,vol,rap,v1,v2,v3,num; + double *a,*b,*c,*d; + double *ma,*mb,*mc,*md,mm[6]; + int j,ia,ib,ic,id,iadr; + + cal = CALLIM; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + abx = b[0] - a[0]; + aby = b[1] - a[1]; + abz = b[2] - a[2]; + + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + if ( vol <= 0. ) return(cal); + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) { + //printf("--- INVALID METRIC : DET (%d) %e\n",iel,det); + return(cal); + } + det = sqrt(det) * vol; + /* edge lengths */ + h1 = mm[0]*abx*abx + mm[3]*aby*aby + mm[5]*abz*abz \ + + 2.0*(mm[1]*abx*aby + mm[2]*abx*abz + mm[4]*aby*abz); + h2 = mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \ + + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz); + h3 = mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \ + + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz); + + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \ + + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz); + h5 = mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \ + + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz); + h6 = mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \ + + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz); + + /* quality */ + rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + //if ( det > EPS1 * num ) completement arbitraire comme seuil!!!! + cal = num / det; + if(cal >= CALLIM) printf(" %d %e %e %e %e\n",iel,cal,num,det,vol); + + assert(cal < CALLIM); + return(cal); +} + +/* compute tetra quality iso */ +double MMG_caltet5_iso(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz; + double h1,h2,h3,h4,h5,h6,vol,v1,v2,v3,rap,num; + double *a,*b,*c,*d; + int ia,ib,ic,id; +double h; + + cal = CALLIM; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + h1 = sol->met[ia]; + h2 = sol->met[ib]; + h3 = sol->met[ic]; + h4 = sol->met[id]; + h = 0.25*(h1 + h2 + h3 + h4); + + /* volume */ + abx = b[0] - a[0]; + aby = b[1] - a[1]; + abz = b[2] - a[2]; + + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + if ( vol <= 0. ) return(cal); + + /* max edge */ + h1 = abx*abx + aby*aby + abz*abz; + h2 = acx*acx + acy*acy + acz*acz; + h3 = adx*adx + ady*ady + adz*adz; + + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + + /* quality */ + rap = h1*h1 + h2*h2 + h3*h3 + h4*h4 + h5*h5 + h6*h6; + num = sqrt(rap) * rap; + cal = num / vol; + assert( cal < CALLIM ); + + return(cal); +} + + +/* compute tetra quality iso */ +double MMG_caltet_iso(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz; + double h1,h2,h3,h4,h5,h6,vol,v1,v2,v3,rap,num; + double *a,*b,*c,*d; + int ia,ib,ic,id; + + cal = CALLIM; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + abx = b[0] - a[0]; + aby = b[1] - a[1]; + abz = b[2] - a[2]; + + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + if ( vol <= 0. ) { + /*tmp = pt->v[2]; + pt->v[2] =pt->v[1]; + pt->v[1] = tmp;*/ + //printf("arg on a un vol nul!!%8e \n ",vol); + return(cal);} + + /* max edge */ + h1 = abx*abx + aby*aby + abz*abz; + h2 = acx*acx + acy*acy + acz*acz; + h3 = adx*adx + ady*ady + adz*adz; + + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + + /* quality */ + rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + //if ( vol > EPS1 * num ) completement arbitraire comme seuil!!!! + cal = num / vol; + assert( cal < CALLIM ); + + return(cal); +} + + +static double determ(double ab[3],double ac[3],double *mm) { + double a1,a2,a3,a4,a5,a6,m0,m1,m2,m3; + + a1 = mm[0]*ab[0] + mm[1]*ab[1] + mm[2]*ab[2]; + a2 = mm[1]*ab[0] + mm[3]*ab[1] + mm[4]*ab[2]; + a3 = mm[2]*ab[0] + mm[4]*ab[1] + mm[5]*ab[2]; + + a4 = mm[0]*ac[0] + mm[1]*ac[1] + mm[2]*ac[2]; + a5 = mm[1]*ac[0] + mm[3]*ac[1] + mm[4]*ac[2]; + a6 = mm[2]*ac[0] + mm[4]*ac[1] + mm[5]*ac[2]; + + m0 = a1*ab[0] + a2*ab[1] + a3*ab[2]; + m1 = a4*ab[0] + a5*ab[1] + a6*ab[2]; + m2 = a1*ac[0] + a2*ac[1] + a3*ac[2]; + m3 = a4*ac[0] + a5*ac[1] + a6*ac[2]; + + return(m0*m3 - m1*m2); +} + + +/* compute tetra quality for output (same as GHS3D) + note: must be normalized by ALPHAC */ +double MMG_calte1_ani(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,ab[3],ac[3],ad[3],bc[3],bd[3],cd[3]; + double h1,h2,h3,h4,h5,h6,rapmax,vol,det,v1,v2,v3; + double air,dd,num; + double *a,*b,*c,*d; + double *ma,*mb,*mc,*md,mm[6];; + int j,ia,ib,ic,id,iadr; + + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(0.0); + cal = CALLIM; + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + ab[0] = b[0] - a[0]; + ab[1] = b[1] - a[1]; + ab[2] = b[2] - a[2]; + + ac[0] = c[0] - a[0]; + ac[1] = c[1] - a[1]; + ac[2] = c[2] - a[2]; + + ad[0] = d[0] - a[0]; + ad[1] = d[1] - a[1]; + ad[2] = d[2] - a[2]; + + v1 = ac[1]*ad[2] - ac[2]*ad[1]; + v2 = ac[2]*ad[0] - ac[0]*ad[2]; + v3 = ac[0]*ad[1] - ac[1]*ad[0]; + vol = ab[0] * v1 + ab[1] * v2 + ab[2] * v3; + if ( vol <= 0. ) return(cal); + + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) { + if(iel) printf("INVALID METRIC : DET (%d) %e\n",iel,det); + return(cal); + } + det = sqrt(det) * vol; + + /* edge lengths */ + rapmax = 0.0; + h1 = mm[0]*ab[0]*ab[0] + mm[3]*ab[1]*ab[1] + mm[5]*ab[2]*ab[2] \ + + 2.0*(mm[1]*ab[0]*ab[1] + mm[2]*ab[0]*ab[2] + mm[4]*ab[1]*ab[2]); + rapmax = M_MAX(rapmax,h1); + h2 = mm[0]*ac[0]*ac[0] + mm[3]*ac[1]*ac[1] + mm[5]*ac[2]*ac[2] \ + + 2.0*(mm[1]*ac[0]*ac[1] + mm[2]*ac[0]*ac[2] + mm[4]*ac[1]*ac[2]); + rapmax = M_MAX(rapmax,h2); + h3 = mm[0]*ad[0]*ad[0] + mm[3]*ad[1]*ad[1] + mm[5]*ad[2]*ad[2] \ + + 2.0*(mm[1]*ad[0]*ad[1] + mm[2]*ad[0]*ad[2] + mm[4]*ad[1]*ad[2]); + rapmax = M_MAX(rapmax,h3); + + bc[0] = c[0] - b[0]; + bc[1] = c[1] - b[1]; + bc[2] = c[2] - b[2]; + + bd[0] = d[0] - b[0]; + bd[1] = d[1] - b[1]; + bd[2] = d[2] - b[2]; + + cd[0] = d[0] - c[0]; + cd[1] = d[1] - c[1]; + cd[2] = d[2] - c[2]; + + h4 = mm[0]*bd[0]*bd[0] + mm[3]*bd[1]*bd[1] + mm[5]*bd[2]*bd[2] \ + + 2.0*(mm[1]*bd[0]*bd[1] + mm[2]*bd[0]*bd[2] + mm[4]*bd[1]*bd[2]); + rapmax = M_MAX(rapmax,h4); + h5 = mm[0]*cd[0]*cd[0] + mm[3]*cd[1]*cd[1] + mm[5]*cd[2]*cd[2] \ + + 2.0*(mm[1]*cd[0]*cd[1] + mm[2]*cd[0]*cd[2] + mm[4]*cd[1]*cd[2]); + rapmax = M_MAX(rapmax,h5); + h6 = mm[0]*bc[0]*bc[0] + mm[3]*bc[1]*bc[1] + mm[5]*bc[2]*bc[2] \ + + 2.0*(mm[1]*bc[0]*bc[1] + mm[2]*bc[0]*bc[2] + mm[4]*bc[1]*bc[2]); + rapmax = M_MAX(rapmax,h6); + + /* surfaces */ + dd = determ(bd,bc,mm); + air = sqrt(dd); + + dd = determ(ac,ad,mm); + air += sqrt(dd); + + dd = determ(ad,ab,mm); + air += sqrt(dd); + + dd = determ(ab,ac,mm); + air += sqrt(dd); + + /* quality */ + num = sqrt(rapmax) * air; + cal = num / det; + assert( cal < CALLIM ); + + return(cal); +} + + +double MMG_calte1_iso(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz; + double h1,h2,h3,h4,h5,h6,rapmax,vol,v1,v2,v3; + double s1,s2,s3,s4,dd,d2,num; + double *a,*b,*c,*d; + int ia,ib,ic,id; + + cal = CALLIM; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + abx = b[0] - a[0]; + aby = b[1] - a[1]; + abz = b[2] - a[2]; + + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + if ( vol <= 0. ) return(cal); + + /* max edge */ + rapmax = 0.0; + h1 = abx*abx + aby*aby + abz*abz; + rapmax = M_MAX(rapmax,h1); + h2 = acx*acx + acy*acy + acz*acz; + rapmax = M_MAX(rapmax,h2); + h3 = adx*adx + ady*ady + adz*adz; + rapmax = M_MAX(rapmax,h3); + + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + rapmax = M_MAX(rapmax,h4); + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + rapmax = M_MAX(rapmax,h5); + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + rapmax = M_MAX(rapmax,h6); + + /* surface */ + dd = cdy*bdz - cdz*bdy; + d2 = dd * dd; + dd = cdz*bdx - cdx*bdz; + d2 = d2 + dd * dd; + dd = cdx*bdy - cdy*bdx; + d2 = d2 + dd * dd; + s1 = sqrt(d2); + + s2 = sqrt(v1*v1 + v2*v2 + v3*v3); + + dd = bdy*adz - bdz*ady; + d2 = dd * dd; + dd = bdz*adx - bdx*adz; + d2 = d2 + dd * dd; + dd = bdx*ady - bdy*adx; + d2 = d2 + dd * dd; + s3 = sqrt(d2); + + dd = aby*acz - abz*acy; + d2 = dd * dd; + dd = abz*acx - abx*acz; + d2 = d2 + dd * dd; + dd = abx*acy - aby*acx; + d2 = d2 + dd * dd; + s4 = sqrt(d2); + + /* quality */ + num = sqrt(rapmax) * (s1+s2+s3+s4); + cal = num / vol; + assert( cal < CALLIM ); + + return(cal); +} + +/* compute tetra quality aniso : (ia ib ic id) and (ie ib id ic) */ +int MMG_caltet2_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab) { + pTetra pt; + double cal,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz; + double bex,bey,bez,ecx,ecy,ecz,edx,edy,edz; + double h1,h2,h3,h4,h5,h6,det,dete,vol,vole,rap,v1,v2,v3; + double h1e,h2e,h3e,h4e,h5e,h6e,num; + double *a,*b,*c,*d,*e; + double *ma,*mb,*mc,*md,mm[6],mme[6],*me; + int j,ia,ib,ic,id,iadr; + + cal = CALLIM; + caltab[0] = cal; + caltab[1] = cal; + pt = &mesh->tetra[iel]; + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ie-1)*sol->offset + 1; + me = &sol->met[iadr]; + + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) { + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + mme[j] = 0.25 * (me[j]+mb[j]+mc[j]+md[j]); + } + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + e = mesh->point[ie].c; + + /* volume */ + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bax = a[0] - b[0]; + bay = a[1] - b[1]; + baz = a[2] - b[2]; + + bex = e[0] - b[0]; + bey = e[1] - b[1]; + bez = e[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + + v1 = bdy*bcz - bdz*bcy; + v2 = bdz*bcx - bdx*bcz; + v3 = bdx*bcy - bdy*bcx; + + vol = bax * v1 + bay * v2 + baz * v3; + if ( vol <= 0. ) return(0); + + vole = -bex * v1 - bey * v2 - bez * v3; + if ( vole <= 0. ) return(0); + + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) return(0); + + dete = mme[0] * ( mme[3]*mme[5] - mme[4]*mme[4]) \ + - mme[1] * ( mme[1]*mme[5] - mme[2]*mme[4]) \ + + mme[2] * ( mme[1]*mme[4] - mme[2]*mme[3]); + if ( dete < EPSOK ) return(0); + + det = sqrt(det) * vol; + + /* edge lengths */ + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + h1 = mm[0]*bax*bax + mm[3]*bay*bay + mm[5]*baz*baz \ + + 2.0*(mm[1]*bax*bay + mm[2]*bax*baz + mm[4]*bay*baz); + h2 = mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \ + + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz); + h3 = mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \ + + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz); + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \ + + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz); + h5 = mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \ + + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz); + h6 = mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \ + + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz); + + /* quality */ + rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + caltab[0] = num / det; + if ( caltab[0] > crit ) return(0); + + dete = sqrt(dete) * vole; + ecx = c[0] - e[0]; + ecy = c[1] - e[1]; + ecz = c[2] - e[2]; + + edx = d[0] - e[0]; + edy = d[1] - e[1]; + edz = d[2] - e[2]; + + h1e = mme[0]*bex*bex + mme[3]*bey*bey + mme[5]*bez*bez \ + + 2.0*(mme[1]*bex*bey + mme[2]*bex*bez + mme[4]*bey*bez); + h2e = mme[0]*ecx*ecx + mme[3]*ecy*ecy + mme[5]*ecz*ecz \ + + 2.0*(mme[1]*ecx*ecy + mme[2]*ecx*ecz + mme[4]*ecy*ecz); + h3e = mme[0]*edx*edx + mme[3]*edy*edy + mme[5]*edz*edz \ + + 2.0*(mme[1]*edx*edy + mme[2]*edx*edz + mme[4]*edy*edz); + + h4e = mme[0]*bdx*bdx + mme[3]*bdy*bdy + mme[5]*bdz*bdz \ + + 2.0*(mme[1]*bdx*bdy + mme[2]*bdx*bdz + mme[4]*bdy*bdz); + h5e = mme[0]*cdx*cdx + mme[3]*cdy*cdy + mme[5]*cdz*cdz \ + + 2.0*(mme[1]*cdx*cdy + mme[2]*cdx*cdz + mme[4]*cdy*cdz); + h6e = mme[0]*bcx*bcx + mme[3]*bcy*bcy + mme[5]*bcz*bcz \ + + 2.0*(mme[1]*bcx*bcy + mme[2]*bcx*bcz + mme[4]*bcy*bcz); + + rap = h1e + h2e + h3e + h4e + h5e + h6e; + num = sqrt(rap) * rap; + caltab[1] = ( sqrt(rap) * rap ) / dete; + + if ( caltab[1] > crit ) return(0); + + return(1); +} + + +/* compute tetra quality iso : (ia ib ic id) and (ie ib id ic) */ +int MMG_caltet2_iso(pMesh mesh,pSol sol,int iel,int ie,double crit,double * caltab) { + pTetra pt; + double cal,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz; + double bex,bey,bez,ecx,ecy,ecz,edx,edy,edz; + double h1,h2,h3,h4,h5,h6,vol,vole,rap,v1,v2,v3; + double h1e,h2e,h3e,num; + double *a,*b,*c,*d,*e; + int ia,ib,ic,id; + + cal = CALLIM; + caltab[0] = cal; + caltab[1] = cal; + pt = &mesh->tetra[iel]; + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + e = mesh->point[ie].c; + + /* volume */ + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bax = a[0] - b[0]; + bay = a[1] - b[1]; + baz = a[2] - b[2]; + + bex = e[0] - b[0]; + bey = e[1] - b[1]; + bez = e[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + + v1 = bdy*bcz - bdz*bcy; + v2 = bdz*bcx - bdx*bcz; + v3 = bdx*bcy - bdy*bcx; + vol = bax * v1 + bay * v2 + baz * v3; + if ( vol <= 0. ) return(0); + + vole = -bex * v1 - bey * v2 - bez * v3; + if ( vole <= 0. ) return(0); +///////////////////// +/* +caltab[0] = MMG_caltetrao(mesh,sol,iel); +if ( caltab[0] > crit ) { + return(0); +} +pt = &mesh->tetra[0]; +pt->v[0] = ie; +pt->v[1] = ib; +pt->v[2] = id; +pt->v[3] = ic; +caltab[1] = MMG_caltetrao(mesh,sol,0); +if ( caltab[1] > crit ) { + return(0); +} +return(1); */ +//////////////////// + + /* edge lengths */ + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + + h1 = bax*bax + bay*bay + baz*baz; + h2 = acx*acx + acy*acy + acz*acz; + h3 = adx*adx + ady*ady + adz*adz; + + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + + /* quality */ + rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + caltab[0] = num / vol; + + if ( caltab[0] > crit ) return(0); + + ecx = c[0] - e[0]; + ecy = c[1] - e[1]; + ecz = c[2] - e[2]; + + edx = d[0] - e[0]; + edy = d[1] - e[1]; + edz = d[2] - e[2]; + + h1e = bex*bex + bey*bey + bez*bez; + h2e = ecx*ecx + ecy*ecy + ecz*ecz; + h3e = edx*edx + edy*edy + edz*edz; + + rap = h1e + h2e + h3e + h4 + h5 + h6; + num = sqrt(rap) * rap; + caltab[1] = num / vole; + + if ( caltab[1] > crit ) return(0); + + return(1); +} + +/* compute tetra quality : 60*max(1/lmin,lmax) + iare : (ia ib ic id) and (ie ib id ic) */ +int MMG_caltet2long_ani(pMesh mesh,pSol sol,int iel,int ie,double crit, double * caltab) { + pTetra pt; + double cal,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz; + double bex,bey,bez,ecx,ecy,ecz,edx,edy,edz; + double h1,h2,h3,h4,h5,h6,det,dete,vol,vole,v1,v2,v3; + double h1e,h2e,h3e,h4e,h5e,h6e; + double *a,*b,*c,*d,*e; + double *ma,*mb,*mc,*md,mm[6],mme[6],*me; + double lmin,lmax; + int j,ia,ib,ic,id,iadr,iarmin,iarmax; + + cal = CALLIM; + caltab[0] = cal; + caltab[1] = cal; + pt = &mesh->tetra[iel]; + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ie-1)*sol->offset + 1; + me = &sol->met[iadr]; + + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) { + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + mme[j] = 0.25 * (me[j]+mb[j]+mc[j]+md[j]); + } + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + e = mesh->point[ie].c; + + /* volume */ + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bax = a[0] - b[0]; + bay = a[1] - b[1]; + baz = a[2] - b[2]; + + bex = e[0] - b[0]; + bey = e[1] - b[1]; + bez = e[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + + v1 = bdy*bcz - bdz*bcy; + v2 = bdz*bcx - bdx*bcz; + v3 = bdx*bcy - bdy*bcx; + + vol = bax * v1 + bay * v2 + baz * v3; + if ( vol <= 0. ) return(0); + + vole = -bex * v1 - bey * v2 - bez * v3; + if ( vole <= 0. ) return(0); + + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) return(0); + + dete = mme[0] * ( mme[3]*mme[5] - mme[4]*mme[4]) \ + - mme[1] * ( mme[1]*mme[5] - mme[2]*mme[4]) \ + + mme[2] * ( mme[1]*mme[4] - mme[2]*mme[3]); + if ( dete < EPSOK ) return(0); + + det = sqrt(det) * vol; + + /* edge lengths */ + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + h1 = mm[0]*bax*bax + mm[3]*bay*bay + mm[5]*baz*baz \ + + 2.0*(mm[1]*bax*bay + mm[2]*bax*baz + mm[4]*bay*baz); + h2 = mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz \ + + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz); + h3 = mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz \ + + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz); + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz \ + + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz); + h5 = mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz \ + + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz); + h6 = mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz \ + + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz); + + /* quality */ + if( h1 < h2 ) { + lmin = h1; + iarmin = 0; + lmax = h2; + iarmax = 1; + } else { + lmin = h2; + iarmin = 1; + lmax = h1; + iarmax = 0; + } + + if( h3 < lmin) { + lmin = h3; + iarmin = 2; + } + if( h3 > lmax) { + lmax = h3; + iarmax = 2; + } + if( h4 < lmin) { + lmin = h4; + iarmin = 3; + } + if( h4 > lmax) { + lmax = h4; + iarmax = 3; + } + if( h5 < lmin) { + lmin = h5; + iarmin = 4; + } + if( h5 > lmax) { + lmax = h5; + iarmax = 4; + } + if( h6 < lmin) { + lmin = h6; + iarmin = 5; + } + if( h6 > lmax) { + lmax = h6; + iarmax = 5; + } + + lmin = sqrt(lmin); + lmax = sqrt(lmax); + lmin = (lmin > 1.) ? lmin : 1./lmin; + lmax = (lmax > 1.) ? lmax : 1./lmax; + if ( lmin > lmax) { + caltab[0] = 60*lmin + iarmin; + } else { + caltab[0] = 60*lmax + iarmax; + } + + /*rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + caltab[0] = num / det; + */ + if ( caltab[0] > crit ) return(0); + + dete = sqrt(dete) * vole; + ecx = c[0] - e[0]; + ecy = c[1] - e[1]; + ecz = c[2] - e[2]; + + edx = d[0] - e[0]; + edy = d[1] - e[1]; + edz = d[2] - e[2]; + + h1e = mme[0]*bex*bex + mme[3]*bey*bey + mme[5]*bez*bez \ + + 2.0*(mme[1]*bex*bey + mme[2]*bex*bez + mme[4]*bey*bez); + h2e = mme[0]*ecx*ecx + mme[3]*ecy*ecy + mme[5]*ecz*ecz \ + + 2.0*(mme[1]*ecx*ecy + mme[2]*ecx*ecz + mme[4]*ecy*ecz); + h3e = mme[0]*edx*edx + mme[3]*edy*edy + mme[5]*edz*edz \ + + 2.0*(mme[1]*edx*edy + mme[2]*edx*edz + mme[4]*edy*edz); + + h4e = mme[0]*bdx*bdx + mme[3]*bdy*bdy + mme[5]*bdz*bdz \ + + 2.0*(mme[1]*bdx*bdy + mme[2]*bdx*bdz + mme[4]*bdy*bdz); + h5e = mme[0]*cdx*cdx + mme[3]*cdy*cdy + mme[5]*cdz*cdz \ + + 2.0*(mme[1]*cdx*cdy + mme[2]*cdx*cdz + mme[4]*cdy*cdz); + h6e = mme[0]*bcx*bcx + mme[3]*bcy*bcy + mme[5]*bcz*bcz \ + + 2.0*(mme[1]*bcx*bcy + mme[2]*bcx*bcz + mme[4]*bcy*bcz); + + if( h1e < h2e ) { + lmin = h1e; + iarmin = 0; + lmax = h2e; + iarmax = 1; + } else { + lmin = h2e; + iarmin = 1; + lmax = h1e; + iarmax = 0; + } + + if( h3e < lmin) { + lmin = h3e; + iarmin = 2; + } + if( h3e > lmax) { + lmax = h3; + iarmax = 2; + } + if( h4 < lmin) { + lmin = h4; + iarmin = 3; + } + if( h4 > lmax) { + lmax = h4; + iarmax = 3; + } + if( h5 < lmin) { + lmin = h5; + iarmin = 4; + } + if( h5 > lmax) { + lmax = h5; + iarmax = 4; + } + if( h6 < lmin) { + lmin = h6; + iarmin = 5; + } + if( h6 > lmax) { + lmax = h6; + iarmax = 5; + } + + + lmin = sqrt(lmin); + lmax = sqrt(lmax); + lmin = (lmin > 1.) ? lmin : 1./lmin; + lmax = (lmax > 1.) ? lmax : 1./lmax; + if ( lmin > lmax) { + caltab[1] = 60*lmin + iarmin; + } else { + caltab[1] = 60*lmax + iarmax; + } + /*rap = h1e + h2e + h3e + h4e + h5e + h6e; + num = sqrt(rap) * rap; + caltab[1] = ( sqrt(rap) * rap ) / dete; + */ + if ( caltab[1] > crit ) return(0); + + return(1); +} + + +/* compute tetra quality iso : (ia ib ic id) and (ie ib id ic) */ +int MMG_caltet2long_iso(pMesh mesh,pSol sol,int iel,int ie,double crit,double * caltab) { + pTetra pt; + double cal,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,bax,bay,baz; + double bex,bey,bez,ecx,ecy,ecz,edx,edy,edz; + double h1,h2,h3,h4,h5,h6,vol,vole,rap,v1,v2,v3; + double h1e,h2e,h3e,num; + double *a,*b,*c,*d,*e; + double lmin,lmax; + int ia,ib,ic,id,iarmin,iarmax; + cal = CALLIM; + caltab[0] = cal; + caltab[1] = cal; + pt = &mesh->tetra[iel]; + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + e = mesh->point[ie].c; + + /* volume */ + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bax = a[0] - b[0]; + bay = a[1] - b[1]; + baz = a[2] - b[2]; + + bex = e[0] - b[0]; + bey = e[1] - b[1]; + bez = e[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + + v1 = bdy*bcz - bdz*bcy; + v2 = bdz*bcx - bdx*bcz; + v3 = bdx*bcy - bdy*bcx; + vol = bax * v1 + bay * v2 + baz * v3; + if ( vol <= 0. ) return(0); + + vole = -bex * v1 - bey * v2 - bez * v3; + if ( vole <= 0. ) return(0); +///////////////////// +/* +caltab[0] = MMG_caltetrao(mesh,sol,iel); +if ( caltab[0] > crit ) { + return(0); +} +pt = &mesh->tetra[0]; +pt->v[0] = ie; +pt->v[1] = ib; +pt->v[2] = id; +pt->v[3] = ic; +caltab[1] = MMG_caltetrao(mesh,sol,0); +if ( caltab[1] > crit ) { + return(0); +} +return(1); */ +//////////////////// + + /* edge lengths */ + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + + h1 = bax*bax + bay*bay + baz*baz; + h2 = acx*acx + acy*acy + acz*acz; + h3 = adx*adx + ady*ady + adz*adz; + + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + + /* quality */ + if( h1 < h2 ) { + lmin = h1; + iarmin = 0; + lmax = h2; + iarmax = 1; + } else { + lmin = h2; + iarmin = 1; + lmax = h1; + iarmax = 0; + } + + if( h3 < lmin) { + lmin = h3; + iarmin = 2; + } + if( h3 > lmax) { + lmax = h3; + iarmax = 2; + } + if( h4 < lmin) { + lmin = h4; + iarmin = 3; + } + if( h4 > lmax) { + lmax = h4; + iarmax = 3; + } + if( h5 < lmin) { + lmin = h5; + iarmin = 4; + } + if( h5 > lmax) { + lmax = h5; + iarmax = 4; + } + if( h6 < lmin) { + lmin = h6; + iarmin = 5; + } + if( h6 > lmax) { + lmax = h6; + iarmax = 5; + } + lmin = sqrt(lmin); + lmax = sqrt(lmax); + lmin = (lmin > 1.) ? lmin : 1./lmin; + lmax = (lmax > 1.) ? lmax : 1./lmax; + //printf("long %e %e %e %e %e %e\n",sqrt(h1),sqrt(h2),sqrt(h3),sqrt(h4),sqrt(h5),sqrt(h6)); + //printf("--lmin %e %e\n",lmin,lmax); + if ( lmin > lmax) { + caltab[0] = 60*lmin + iarmin; + } else { + caltab[0] = 60*lmax + iarmax; + } + rap = h1 + h2 + h3 + h4 + h5 + h6; + num = sqrt(rap) * rap; + cal = num / vol; + + //printf("cal %e ? %e\n",caltab[0],crit); + if ( cal > crit ) return(0); + + ecx = c[0] - e[0]; + ecy = c[1] - e[1]; + ecz = c[2] - e[2]; + + edx = d[0] - e[0]; + edy = d[1] - e[1]; + edz = d[2] - e[2]; + + h1e = bex*bex + bey*bey + bez*bez; + h2e = ecx*ecx + ecy*ecy + ecz*ecz; + h3e = edx*edx + edy*edy + edz*edz; + + if( h1e < h2e ) { + lmin = h1e; + iarmin = 0; + lmax = h2e; + iarmax = 1; + } else { + lmin = h2e; + iarmin = 1; + lmax = h1e; + iarmax = 0; + } + + if( h3e < lmin) { + lmin = h3e; + iarmin = 2; + } + if( h3e > lmax) { + lmax = h3; + iarmax = 2; + } + if( h4 < lmin) { + lmin = h4; + iarmin = 3; + } + if( h4 > lmax) { + lmax = h4; + iarmax = 3; + } + if( h5 < lmin) { + lmin = h5; + iarmin = 4; + } + if( h5 > lmax) { + lmax = h5; + iarmax = 4; + } + if( h6 < lmin) { + lmin = h6; + iarmin = 5; + } + if( h6 > lmax) { + lmax = h6; + iarmax = 5; + } + + lmin = sqrt(lmin); + lmax = sqrt(lmax); + lmin = (lmin > 1.) ? lmin : 1./lmin; + lmax = (lmax > 1.) ? lmax : 1./lmax; + //printf("lmin %e %e\n",lmin,lmax); + if ( lmin > lmax) { + caltab[1] = 60*lmin + iarmin; + } else { + caltab[1] = 60*lmax + iarmax; + } + rap = h1e + h2e + h3e + h4 + h5 + h6; + num = sqrt(rap) * rap; + cal = num / vole; + + //printf("cal %e ? %e\n",caltab[1],crit); + if ( cal > crit ) return(0); +// puts("je passe");exit(0); + + return(1); +} + +double MMG_calte3_ani(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,ab[3],ac[3],ad[3],bc[3],bd[3],cd[3]; + double vol,det,v1,v2,v3,air,dd; + double *a,*b,*c,*d; + double *ma,*mb,*mc,*md,mm[6];; + int j,ia,ib,ic,id,iadr; + static double id3[6] ={1.0,0.,0.,1.,0.,1.}; + + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(0.0); + cal = CALLIM; + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + ab[0] = b[0] - a[0]; + ab[1] = b[1] - a[1]; + ab[2] = b[2] - a[2]; + + ac[0] = c[0] - a[0]; + ac[1] = c[1] - a[1]; + ac[2] = c[2] - a[2]; + + ad[0] = d[0] - a[0]; + ad[1] = d[1] - a[1]; + ad[2] = d[2] - a[2]; + + v1 = ac[1]*ad[2] - ac[2]*ad[1]; + v2 = ac[2]*ad[0] - ac[0]*ad[2]; + v3 = ac[0]*ad[1] - ac[1]*ad[0]; + vol = ab[0] * v1 + ab[1] * v2 + ab[2] * v3; + if ( vol <= 0. ) return(cal); + + det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \ + - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \ + + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]); + if ( det < EPSOK ) return(cal); + det = sqrt(det) * vol; + + bc[0] = c[0] - b[0]; + bc[1] = c[1] - b[1]; + bc[2] = c[2] - b[2]; + + bd[0] = d[0] - b[0]; + bd[1] = d[1] - b[1]; + bd[2] = d[2] - b[2]; + + cd[0] = d[0] - c[0]; + cd[1] = d[1] - c[1]; + cd[2] = d[2] - c[2]; + + /* surfaces */ + memcpy(mm,id3,6*sizeof(double)); + dd = determ(bd,bc,mm); + air = dd; +if ( iel ==17460 ) printf("aire1 %E\n",sqrt(dd)); + + dd = determ(ac,ad,mm); +if ( iel ==17460 ) printf("aire2 %E\n",sqrt(dd)); + air = M_MAX(air,dd); + + dd = determ(ad,ab,mm); +if ( iel ==17460 ) printf("aire3 %E\n",sqrt(dd)); + air = M_MAX(air,dd); + + dd = determ(ab,ac,mm); +if ( iel ==17460 ) printf("aire4 %E\n",sqrt(dd)); + air = M_MAX(air,dd); + + /* quality */ + if ( iel == 20496 ) { + printf("vol %E \n",vol); + printf("a %d: %f %f %f\n",ia,a[0],a[1],a[2]); + printf("b %d: %f %f %f\n",ib,b[0],b[1],b[2]); + printf("c %d: %f %f %f\n",ic,c[0],c[1],c[2]); + printf("d %d: %f %f %f\n",id,d[0],d[1],d[2]); + } + cal = 3.0*vol / sqrt(air); + + return(cal); +} + +/* compute tetra quality to be the cubic mean ration : 15552 * V^2/(somme l^2)^3 */ +double MMG_caltetcubic(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz; + double h1,h2,h3,h4,h5,h6,vol,rap,v1,v2,v3; + double *a,*b,*c,*d; + int ia,ib,ic,id; + + cal = 0.; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + a = mesh->point[ia].c; + b = mesh->point[ib].c; + c = mesh->point[ic].c; + d = mesh->point[id].c; + + /* volume */ + abx = b[0] - a[0]; + aby = b[1] - a[1]; + abz = b[2] - a[2]; + + acx = c[0] - a[0]; + acy = c[1] - a[1]; + acz = c[2] - a[2]; + + adx = d[0] - a[0]; + ady = d[1] - a[1]; + adz = d[2] - a[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + if ( vol <= 0. ) return(cal); + vol /= 6.; + + /* edge */ + h1 = abx*abx + aby*aby + abz*abz; + h2 = acx*acx + acy*acy + acz*acz; + h3 = adx*adx + ady*ady + adz*adz; + + bcx = c[0] - b[0]; + bcy = c[1] - b[1]; + bcz = c[2] - b[2]; + + bdx = d[0] - b[0]; + bdy = d[1] - b[1]; + bdz = d[2] - b[2]; + + cdx = d[0] - c[0]; + cdy = d[1] - c[1]; + cdz = d[2] - c[2]; + + h4 = bdx*bdx + bdy*bdy + bdz*bdz; + h5 = cdx*cdx + cdy*cdy + cdz*cdz; + h6 = bcx*bcx + bcy*bcy + bcz*bcz; + + /* quality */ + rap = h1 + h2 + h3 + h4 + h5 + h6; + cal = vol*vol; + cal *= 15552.; + cal = exp(0.3333333333*log(cal)); + //cal = pow(cal,0.33333333333); + cal = cal / rap; + + return(cal); +} + +/* compute tetra quality : 60*max(1/lmin,lmax) + iare*/ +double MMG_callong(pMesh mesh,pSol sol,int iel) { + pTetra pt; + double *ca,*cb,len; + double *ma,*mb,lmin,lmax,cal; + double ux,uy,uz,dd1,sa,dd2,sb,dd,rap; + int i,ia,ib,iadr,iarmin,iarmax,ipa,ipb; + + cal = CALLIM; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(cal); + + lmax = 0.; + lmin = CALLIM; + iarmin = 0; + iarmax = 0; + for (i=0; i<6; i++) { + + /* edge length */ + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + if(sol->offset==6) { + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + + dd1 = ma[0]*ux*ux + ma[3]*uy*uy + ma[5]*uz*uz \ + + 2.0*(ma[1]*ux*uy + ma[2]*ux*uz + ma[4]*uy*uz); + if ( dd1 <= 0.0 ) dd1 = 0.0; + + dd2 = mb[0]*ux*ux + mb[3]*uy*uy + mb[5]*uz*uz \ + + 2.0*(mb[1]*ux*uy +mb[2]*ux*uz + mb[4]*uy*uz); + if ( dd2 <= 0.0 ) dd2 = 0.0; + + /*longueur approchee*/ + /*precision a 3.5 10e-3 pres*/ + if(fabs(dd1-dd2) < 0.05 ) { + //printf("bonne precision %e \n",sqrt(0.5*(dd1+dd2)) - (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0 ); + len = sqrt(0.5*(dd1+dd2)); + } else{ + len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0; + } + } else { + sa = *ma; + sb = *mb; + + ux = cb[0] - ca[0]; + uy = cb[1] - ca[1]; + uz = cb[2] - ca[2]; + dd = sqrt(ux*ux + uy*uy + uz*uz); + + rap = (sb - sa) / sa; + if ( fabs(rap) < EPS1 ) + /*len = dd * (2.0-EPS1) / (2.0*sa);*/ + len = dd / sa; + else + /*len = max(dd/sa,dd/sb);*/ + len = dd * (1.0/sa + 1.0/sb + 8.0 / (sa+sb)) / 6.0; + + } + if ( len < lmin ) { + lmin = len; + iarmin = i; + } + if ( len > lmax ) { + lmax = len; + iarmax = i; + } + } + lmin = (lmin > 1.) ? lmin : 1./lmin; + lmax = (lmax > 1.) ? lmax : 1./lmax; + if ( lmin > lmax) { + cal = 60*lmin + iarmin; + } else { + cal = 60*lmax + iarmax; + } + return(cal); +} diff --git a/contrib/mmg3d/build/sources/queue.c b/contrib/mmg3d/build/sources/queue.c new file mode 100644 index 0000000000..2756bf3bb8 --- /dev/null +++ b/contrib/mmg3d/build/sources/queue.c @@ -0,0 +1,167 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +pQueue MMG_kiuini(pMesh mesh,int nbel,double declic,int base) { + pQueue q; + pTetra pt; + int k; + + q = (Queue*)M_malloc(sizeof(Queue),"kiuini"); + assert(q); + q->stack = (int*)M_calloc((1+nbel),sizeof(int),"kiuini.stack"); + assert(q->stack); + + q->cur = 0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] || pt->qual < declic ) continue; + else if ( base > 0 && pt->flag < base ) continue; + + q->stack[q->cur] = k; + q->cur = k; + } + + return(q); +} + + +void MMG_kiufree(pQueue q) { + M_free(q->stack); + M_free(q); +} + + +int MMG_kiudel(pQueue q,int iel) { + int k; + + if ( !q->stack[0] ) + return(0); + + else if ( q->cur != iel && !q->stack[iel] ) + return(0); + + else if ( iel == q->stack[0] ) { + if ( iel == q->cur ) { + q->cur = 0; + q->stack[0] = 0; + return(1); + } + else { + q->stack[0] = q->stack[iel]; + q->stack[iel] = 0; + return(1); + } + } + + else { + for (k=iel-1; k>0; k--) + if ( q->stack[k] == iel ) break; +assert(k>0); + if ( iel == q->cur ) { + q->cur = k; + q->stack[k] = 0; + q->stack[iel] = 0; + return(1); + } + else { + q->stack[k] = q->stack[iel]; + q->stack[iel] = 0; + return(1); + } + } + + return(0); +} + + +int MMG_kiuput(pQueue q,int iel) { + int k; + + if ( !q->stack[0] ) + return(0); + + else if ( iel == q->cur || q->stack[iel] ) + return(0); + + else if ( iel > q->cur ) { + q->stack[q->cur] = iel; + q->stack[iel] = 0; + q->cur = iel; + return(1); + } + + else if ( iel < q->stack[0] ) { + q->stack[iel] = q->stack[0]; + q->stack[0] = iel; + return(1); + } + + else { + for (k=iel-1; k>=0; k--) + if ( q->stack[k] ) break; +assert(k>-1); + q->stack[iel] = q->stack[k]; + q->stack[k] = iel; + return(1); + } + + return(0); +} + + +int MMG_kiupop(pQueue q) { + int cur; + + cur = q->stack[0]; + q->stack[0] = q->stack[cur]; + q->stack[cur] = 0; + if ( q->cur == cur ) q->cur = 0; + + return(cur); +} + + diff --git a/contrib/mmg3d/build/sources/ratio.c b/contrib/mmg3d/build/sources/ratio.c new file mode 100644 index 0000000000..a975e6da84 --- /dev/null +++ b/contrib/mmg3d/build/sources/ratio.c @@ -0,0 +1,435 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +/* +ratio = +tet equi : 1. +tet rect (1 1 sqrt(2)) : 3.73 vs 1.93 (avec sqrt(lmax/lmin)) +tet rect (1 1/sqrt(2) 1/sqrt(2)) : 2.2413 vs 1.49 +*/ + +#include "mesh.h" + +int MMG_gauss(double mat[6][6],double rhs[6],double* met); + + +/*compute the aniso ratio for an element k*/ +double MMG_rao(pMesh mesh,int k,FILE* inm) { + pTetra pt; + pPoint ppa,ppb; + double edg[6][3],mat[6][6],met[6],rhs[6]; + double lambda[3],v[3][3],lmin,lmax,rao; +// double bufd[GmfMaxTyp]; + int i,j; + + pt = &mesh->tetra[k]; + + /*compute the ellipsoide*/ + for (i=0 ; i<6 ; i++) + rhs[i] = 1; + + for (i=0 ; i<6 ; i++) { + ppa = &mesh->point[pt->v[MMG_iare[i][0]]]; + ppb = &mesh->point[pt->v[MMG_iare[i][1]]]; + for (j=0 ; j<3 ; j++) { + edg[i][j] = ppb->c[j] - ppa->c[j]; + } + mat[i][0] = edg[i][0]*edg[i][0]; + mat[i][1] = 2*edg[i][0]*edg[i][1]; + mat[i][2] = 2*edg[i][0]*edg[i][2]; + mat[i][3] = edg[i][1]*edg[i][1]; + mat[i][4] = 2*edg[i][1]*edg[i][2]; + mat[i][5] = edg[i][2]*edg[i][2]; + } + MMG_gauss(mat,rhs,met); + + /*find the eigenvalues of the metric*/ + if ( !eigenv(1,met,lambda,v) ) { + for (j=0 ; j<6 ; j++) + printf("%e %e %e %e %e %e\n",mat[j][0],mat[j][1],mat[j][2],mat[j][3],mat[j][4],mat[j][5]); + printf("\n met %e %e %e %e %e %e\n",met[0],met[1],met[2],met[3],met[4],met[5]); + puts("pbs eigen"); + return(0); + } + /*calculate the aniso ratio obtained*/ + lmin = M_MIN(lambda[0],lambda[1]); + lmin = M_MIN(lmin,lambda[2]); + lmax = M_MAX(lambda[0],lambda[1]); + lmax = M_MAX(lmax,lambda[2]); + rao = sqrt(lmax / lmin); + if(inm) { + /*for (i=0; i<6; i++) + bufd[i] = met[i]; + + bufd[2] = met[3]; + bufd[3] = met[2];*/ + fprintf(inm,"%.15lg \n",rao); + } + + return(rao); +} + + +int MMG_avgmet(pSol sol,pTetra pt,double* mm) { + double *ma,*mb,*mc,*md,h1,h2,h3,h4,h; + int ia,ib,ic,id,j,iadr; + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + + if (sol->offset==1) { + h1 = sol->met[ia]; + h2 = sol->met[ib]; + h3 = sol->met[ic]; + h4 = sol->met[id]; + h = 0.25*(h1 + h2 + h3 + h4); + mm[0] = h; + mm[1] = 0; + mm[2] = 0; + mm[3] = h; + mm[4] = 0; + mm[5] = h; + } else { + + /* average metric */ + memset(mm,0,6*sizeof(double)); + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + iadr = (ib-1)*sol->offset + 1; + mb = &sol->met[iadr]; + iadr = (ic-1)*sol->offset + 1; + mc = &sol->met[iadr]; + iadr = (id-1)*sol->offset + 1; + md = &sol->met[iadr]; + for (j=0; j<6; j++) + mm[j] = 0.25 * (ma[j]+mb[j]+mc[j]+md[j]); + + } + + return(1); +} + +/* compute the prescribed and obtained anisotropic ratio + print histo + save the ratio in a file +*/ +int MMG_ratio(pMesh mesh, pSol sol,char* firaoame) { + FILE *inm; + pTetra pt; + double met[6]; + double lambda[3],v[3][3],lmin,lmax,rao; + int k,ne,typ; + char *ptr,data[128],chaine[128]; + double rapmin,rapmax,rapavg; + int his[10],rapnum; + int iel,ir,nn,nex,ielreal; + static double bd[9] = {1.0, 2., 10.0, 50., 100., 200., 500., 1000., 5000. }; + + /*save ratio obtained ?*/ + inm = 0; + if(firaoame) { + strcpy(data,firaoame); + ptr = strstr(data,".meshb"); + if ( ptr ) *ptr = '\0'; + else { + ptr = strstr(data,".mesh"); + if ( ptr ) { + *ptr = '\0'; + } + } + strcat(data,".sol"); + if( !(inm = fopen(data,"w")) ) { + fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); + return(0); + } + else + fprintf(stdout," %%%% %s OPENED\n",data); + + /*entete fichier*/ + strcpy(&chaine[0],"MeshVersionFormatted 2\n"); + fprintf(inm,"%s",chaine); + strcpy(&chaine[0],"\n\nDimension 3\n"); + fprintf(inm,"%s ",chaine); + + typ = 1; + + ne = 0; + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) continue; + ne++; + } + strcpy(&chaine[0],"\n\nSolAtTetrahedra\n"); + fprintf(inm,"%s",chaine); + fprintf(inm,"%d\n",ne); + fprintf(inm,"%d %d\n",1,typ); + + } + + if ( abs(mesh->info.imprim) > 7 ) { + + /*ratio prescribed*/ + + rapmin = 1.e20; + rapmax = -1.e20; + rapavg = 0.0; + rapnum = 0; + iel = 0; + ielreal = 0; + nn = 0; + nex = 0; + + for (k=0; k<10; k++) his[k] = 0; + + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) { + nex++; + continue; + } + nn++; + + /*mean metric*/ + MMG_avgmet(sol,pt,met); + + /*find the eigenvalues of the prescribed metric*/ + if ( !eigenv(1,met,lambda,v) ) { + puts("pbs eigen"); + return(0); + } + + /*calculate the aniso ratio */ + lmin = M_MIN(lambda[0],lambda[1]); + lmin = M_MIN(lmin,lambda[2]); + lmax = M_MAX(lambda[0],lambda[1]); + lmax = M_MAX(lmax,lambda[2]); + rao = sqrt(lmax / lmin); + + /*histo prescribed*/ + ir = (int)rao; + if ( rao > rapmax ) { + rapmax = rao; + iel = k; + ielreal = k - nex; + } + rapavg += rao; + rapnum++; + if ( rao < 17e10 ) { + rapmin = M_MIN(rapmin,rao); + if (rao < bd[3]) { + if (rao > bd[2]) his[3]++; + else if (rao > bd[1]) his[2]++; + else his[1]++; + } + else if (rao < bd[5]) { + if (rao > bd[4]) his[5]++; + else if (rao > bd[3]) his[4]++; + } + else if (rao < bd[6]) his[6]++; + else if (rao < bd[7]) his[7]++; + else if (rao < bd[8]) his[8]++; + else his[9]++; + } + + } + /* print histo ratio obtained*/ + fprintf(stdout,"\n -- ANISOTROPIC RATIO PRESCRIBED %d\n",rapnum); + fprintf(stdout," AVERAGE RATIO %12.4f\n",rapavg / rapnum); + fprintf(stdout," SMALLEST RATIO %12.4f\n",rapmin); + if (rapmax < 1.e4) { + fprintf(stdout," LARGEST RATIO %12.4f\n",rapmax); + } else { + fprintf(stdout," LARGEST RATIO %12.4e\n",rapmax); + } + pt = &mesh->tetra[iel]; + fprintf(stdout," ELEMENT %d (%d) %d %d %d %d\n", + iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + + fprintf(stdout,"\n HISTOGRAMM\n"); + for (k=1; k<9; k++) { + if ( his[k] > 0 ) + fprintf(stdout," %8.2f < R <%8.2f %8d %5.2f %% \n", + bd[k-1],bd[k],his[k],100.*(his[k]/(float)rapnum)); + } + if ( his[9] ) + fprintf(stdout," 5000.00 < R %8d %5.2f %% \n", + his[9],100.*(his[9]/(float)rapnum)); + + } + + rapmin = 1.e20; + rapmax = -1.e20; + rapavg = 0.0; + rapnum = 0; + iel = 0; + ielreal = 0; + nn = 0; + nex = 0; + + for (k=0; k<10; k++) his[k] = 0; + + for(k=1 ; k<=mesh->ne ; k++) { + pt = &mesh->tetra[k]; + if(!pt->v[0]) { + nex++; + continue; + } + nn++; + + rao = MMG_rao(mesh,k,inm); + + /*histo obtained*/ + ir = (int)rao; + if ( rao > rapmax ) { + rapmax = rao; + iel = k; + ielreal = k - nex; + } + rapavg += rao; + rapnum++; + + if ( rao < 17e10 ) { + rapmin = M_MIN(rapmin,rao); + if (rao < bd[3]) { + if (rao > bd[2]) his[3]++; + else if (rao > bd[1]) his[2]++; + else his[1]++; + } + else if (rao < bd[5]) { + if (rao > bd[4]) his[5]++; + else if (rao > bd[3]) his[4]++; + } + else if (rao < bd[6]) his[6]++; + else if (rao < bd[7]) his[7]++; + else if (rao < bd[8]) his[8]++; + else his[9]++; + } + + } + + if(inm) fclose(inm); + + /* print histo ratio obtained*/ + fprintf(stdout,"\n -- ANISOTROPIC RATIO OBTAINED %d\n",rapnum); + fprintf(stdout," AVERAGE RATIO %12.4f\n",rapavg / rapnum); + fprintf(stdout," SMALLEST RATIO %12.4f\n",rapmin); + if (rapmax < 1.e4) { + fprintf(stdout," LARGEST RATIO %12.4f\n",rapmax); + } else { + fprintf(stdout," LARGEST RATIO %12.4e\n",rapmax); + } + pt = &mesh->tetra[iel]; + fprintf(stdout," ELEMENT %d (%d) %d %d %d %d\n", + iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]); + + if ( abs(mesh->info.imprim) < 5 ) return; + + fprintf(stdout,"\n HISTOGRAMM\n"); + for (k=1; k<9; k++) { + if ( his[k] > 0 ) + fprintf(stdout," %8.2f < R <%8.2f %8d %5.2f %% \n", + bd[k-1],bd[k],his[k],100.*(his[k]/(float)rapnum)); + } + if ( his[9] ) + fprintf(stdout," 5000.00 < R %8d %5.2f %% \n", + his[9],100.*(his[9]/(float)rapnum)); + + return(1); +} + +/* solve mat*met = rhs */ +int MMG_gauss(double mat[6][6],double rhs[6],double* met) { + int i,j,l; + double tmp,piv; + /*printf("begin : \n"); + for (j=0 ; j<6 ; j++) + printf("%e %e %e %e %e %e\n",mat[j][0],mat[j][1],mat[j][2],mat[j][3],mat[j][4],mat[j][5]); + */ + /* triangularisation*/ + for (i=0 ; i<5 ; i++) { + l = i+1; + while ( (fabs(mat[i][i]) < 1e-8) && (l<6)){ + for (j=0 ; j<6 ; j++) { + tmp = mat[i][j]; + mat[i][j] = mat[l][j]; + mat[l][j] = tmp; + } + tmp = rhs[i]; + rhs[i] = rhs[l]; + rhs[l] = tmp; + + l++; + } + if ((fabs(mat[i][i]) < 1e-8)) { + //puts("WARNING PIV"); + met[0] = 1; + met[1] = 0; + met[2] = 0; + met[3] = 1e7; + met[4] = 10; + met[5] = 1e7; + return(1); + } + for (j=i+1 ; j<6 ; j++) { + piv = mat[j][i]; + for (l=0 ; l<6 ; l++) { + mat[j][l] -= piv*mat[i][l] / mat[i][i]; + } + rhs[j] -= piv*rhs[i]/ mat[i][i]; + } + } + /*remontee*/ + met[5] = rhs[5] / mat[5][5]; + for(j=4 ; j>=0 ; j--){ + met[j] = rhs[j]; + for(l=j+1 ; l<6 ; l++) { + met[j] += -mat[j][l]*met[l]; + } + met[j] /= mat[j][j]; + } + + return(1); +} diff --git a/contrib/mmg3d/build/sources/scalem.c b/contrib/mmg3d/build/sources/scalem.c new file mode 100644 index 0000000000..91fc613612 --- /dev/null +++ b/contrib/mmg3d/build/sources/scalem.c @@ -0,0 +1,230 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_scaleMesh(pMesh mesh,pSol sol) { + pTetra pt; + pPoint ppt; + pDispl pd; + Info *info; + double dd,d1; + double *m,*mold; + int i,k,iadr,alloc,ii,jj,kk; + double lambda[3],v[3][3]; + + /* mark used vertices */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + for (i=0; i<4; i++) { + ppt = &mesh->point[ pt->v[i] ]; + ppt->tag &= ~M_UNUSED; + } + } + + if (abs(mesh->info.option)==10) { + return(1); + } + + /* compute bounding box */ + info = &mesh->info; + for (i=0; i<3; i++) { + info->min[i] = DBL_MAX; + info->max[i] = -DBL_MAX; + } + + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + for (i=0; i<3; i++) { + if ( ppt->c[i] > info->max[i] ) info->max[i] = ppt->c[i]; + if ( ppt->c[i] < info->min[i] ) info->min[i] = ppt->c[i]; + } + } + info->delta = info->max[0]-info->min[0]; + dd = info->max[1]-info->min[1]; + if ( dd > info->delta ) + info->delta = dd; + dd = info->max[2]-info->min[2]; + if ( dd > info->delta ) + info->delta = dd; + if ( info->delta < EPS30 ) { + fprintf(stdout," ## Unable to scale mesh.\n"); + return(0); + } + /* normalize coordinates */ + alloc = mesh->disp != NULL; + dd = (double)PRECI / info->delta; + if ( !alloc ) { + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ppt->c[0] = dd * (ppt->c[0] - info->min[0]); + ppt->c[1] = dd * (ppt->c[1] - info->min[1]); + ppt->c[2] = dd * (ppt->c[2] - info->min[2]); + } + } + else { + pd = mesh->disp; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ppt->c[0] = dd * (ppt->c[0] - info->min[0]); + ppt->c[1] = dd * (ppt->c[1] - info->min[1]); + ppt->c[2] = dd * (ppt->c[2] - info->min[2]); + + pd->mv[3*(k-1) + 1 + 0] *= dd; + pd->mv[3*(k-1) + 1 + 1] *= dd; + pd->mv[3*(k-1) + 1 + 2] *= dd; + + d1 = pd->mv[3*(k-1) + 1 + 0]*pd->mv[3*(k-1) + 1 + 0] + + pd->mv[3*(k-1) + 1 + 1]*pd->mv[3*(k-1) + 1 + 1] \ + + pd->mv[3*(k-1) + 1 + 2]*pd->mv[3*(k-1) + 1 + 2]; + if ( d1 > EPS2 ) ppt->tag |= M_MOVE; + } + } + + /* normalize metric */ + if ( !sol->np ) return(1); + + switch (sol->offset) { + case 1: + for (k=1; k<=sol->np; k++) { + sol->met[k] *= dd; + } + break; + + case 6: + dd = 1.0 / (dd*dd); + for (k=1; k<=mesh->np; k++) { + iadr = (k-1)*sol->offset + 1; + m = &sol->met[iadr]; + for (i=0; i<sol->offset; i++) m[i] *= dd; + + /*calcul du log de M*/ + if ( !eigenv(1,m,lambda,v) ) { + printf("WRONG METRIC AT POINT %d -- \n",k); + return(0); + } + for (i=0; i<3; i++) { + if(lambda[i]<=0) { + printf("WRONG METRIC AT POINT %d -- eigenvalue : %e %e %e -- det %e\n",k,lambda[0],lambda[1],lambda[2], + m[0]*(m[3]*m[5]-m[4]*m[4])-m[1]*(m[1]*m[5]-m[2]*m[4])+ + m[2]*(m[1]*m[4]-m[2]*m[3])); + printf("WRONG METRIC AT POINT %d -- metric %e %e %e %e %e %e\n",k,m[0],m[1],m[2],m[3],m[4],m[5]); + return(0); + } + lambda[i] = log(lambda[i]); + } + mold = &sol->metold[iadr]; + kk = 0; + for (ii=0; ii<3; ii++) { + for (jj=ii; jj<3; jj++) { + mold[kk] = lambda[0]*v[0][ii]*v[0][jj] + + lambda[1]*v[1][ii]*v[1][jj] + + lambda[2]*v[2][ii]*v[2][jj]; + kk = kk+1; + } + } + } + break; + default: + fprintf(stderr," ## SPECIFIC DATA NOT USED.\n"); + exit(2); + } + + /* compute quality */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( pt->v[0] ) { + pt->qual = MMG_caltet(mesh,sol,k); + } + else + pt->qual = 0.0; + } + + return(1); +} + + +int MMG_unscaleMesh(pMesh mesh,pSol sol) { + pPoint ppt; + Info *info; + double dd; + double *m; + int i,k,iadr; + + info = &mesh->info; + + /* de-normalize coordinates */ + dd = info->delta / (double)PRECI; + for (k=1; k<=mesh->np; k++) { + ppt = &mesh->point[k]; + if ( ppt->tag & M_UNUSED ) continue; + ppt->c[0] = ppt->c[0] * dd + info->min[0]; + ppt->c[1] = ppt->c[1] * dd + info->min[1]; + ppt->c[2] = ppt->c[2] * dd + info->min[2]; + } + + /* de-normalize metric */ + sol->np = mesh->np; + if ( sol->offset == 1 ) { + for (k=1; k<=sol->np; k++) sol->met[k] *= dd; + } + else { + dd = 1.0 / (dd*dd); + for (k=1; k<=sol->np; k++) { + iadr = (k-1)*sol->offset + 1; + m = &sol->met[iadr]; + for (i=0; i<6; i++) m[i] *= dd; + } + } + + return(1); +} + + + diff --git a/contrib/mmg3d/build/sources/simu23.c b/contrib/mmg3d/build/sources/simu23.c new file mode 100644 index 0000000000..e9d91c9398 --- /dev/null +++ b/contrib/mmg3d/build/sources/simu23.c @@ -0,0 +1,144 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_simu23(pMesh mesh,pSol sol,int iel,int i,double crit) { + pTetra pt,pt1; + int *adja,iadr,jel,j,ia,ib,s1,s2,s3; + if ( !MMG_getnElt(mesh,3) ) return(-1); + + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(0); + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if ( !adja[i] || (pt->bdryref[i]!=-1)) return(0); + jel = adja[i] / 4; + j = adja[i] % 4; + pt1 = &mesh->tetra[jel]; + + ia = pt->v[i]; + ib = pt1->v[j]; + s1 = pt->v[ MMG_idir[i][0] ]; + s2 = pt->v[ MMG_idir[i][1] ]; + s3 = pt->v[ MMG_idir[i][2] ]; + + /* quality of new tetras */ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = ib; + pt1->v[2] = s1; + pt1->v[3] = s2; + if ( MMG_caltet(mesh,sol,0) > crit ) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + + pt1->v[2] = s2; + pt1->v[3] = s3; + if ( MMG_caltet(mesh,sol,0) > crit ) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + + pt1->v[2] = s3; + pt1->v[3] = s1; + if ( MMG_caltet(mesh,sol,0) > crit ) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + + memset(pt1,0,sizeof(Tetra)); + + /* set function ptr */ +// MMG_swpptr = MMG_swap23; + return(1); +} + + +int MMG_simu32(pMesh mesh,pSol sol,pList list,double crit) { + pTetra pt,pt1; + double caltab[2]; + int *adja,k,adj,ia,ib,s1,s2,s3,iadr,iel,iar; + short voy; + + /* initial qual */ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + /* qual 2 elts */ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + list->qual[1] = caltab[0]; + list->qual[2] = caltab[1]; + + memset(pt1,0,sizeof(Tetra)); + + /* set function ptr */ + MMG_swpptr = MMG_swap32; + return(1); +} diff --git a/contrib/mmg3d/build/sources/simu44.c b/contrib/mmg3d/build/sources/simu44.c new file mode 100644 index 0000000000..c8a20c9e49 --- /dev/null +++ b/contrib/mmg3d/build/sources/simu44.c @@ -0,0 +1,140 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* return 41-42 for config */ +int MMG_simu44(pMesh mesh,pSol sol,pList list,double crit) { + pTetra pt,pt1;; + double caltab[2]; + int ia,ib,s1,s2,s3,s4,iadr,*adja,k,adj,iel,iar; + short voy; + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + do { + /*config 1 tetra 1*/ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + memset(pt1,0,sizeof(Tetra)); + break; + } + list->qual[1] = caltab[0]; + list->qual[2] = caltab[1]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + memset(pt1,0,sizeof(Tetra)); + break; + } + list->qual[3] = caltab[0]; + list->qual[4] = caltab[1]; + + + /* set function ptr */ + MMG_swpptr = MMG_swap44_1; + return(41); + + } while(0); + + /* alternate config */ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + list->qual[1] = caltab[0]; + list->qual[2] = caltab[1]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + memset(pt1,0,sizeof(Tetra)); + return(0); + } + list->qual[3] = caltab[0]; + list->qual[4] = caltab[1]; + + /* set function ptr */ + MMG_swpptr = MMG_swap44_2; + return(42); +} + diff --git a/contrib/mmg3d/build/sources/simu56.c b/contrib/mmg3d/build/sources/simu56.c new file mode 100644 index 0000000000..06671c0b2f --- /dev/null +++ b/contrib/mmg3d/build/sources/simu56.c @@ -0,0 +1,364 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_simu56(pMesh mesh,pSol sol,pList list,double crit) { + pTetra pt,pt1; + double qual[21],caltab[2]; + int j,ia,ib,s1,s2,s3,s4,s5; + int iadr,*adja,k,adj,iel,iar; + short voy; + + for(j = 0 ; j<21 ; j++) { + qual[j] = -1; + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu56_ani: point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + do { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + memset(pt1,0,sizeof(Tetra)); + qual[1] = 0; + break; + } + qual[1] = caltab[0]; + qual[2] = caltab[1]; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[3] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[5] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + list->qual[5] = qual[5]; + list->qual[6] = qual[6]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap56_1; + return(51); + } while(0); + + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + list->qual[3] = qual[7]; + list->qual[4] = qual[8]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[9] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap56_3; + return(53); + } while(0); + + do { + if(!qual[5]) break; + else if(qual[5] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[5] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + } + list->qual[1] = qual[5]; + list->qual[2] = qual[6]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + list->qual[3] = qual[11]; + list->qual[4] = qual[12]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[13] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + list->qual[5] = qual[13]; + list->qual[6] = qual[14]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap56_4; + return(54); + } while(0); + + do { + if(!qual[11]) break; + else if(qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[3] = qual[11]; + list->qual[4] = qual[12]; + + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[15] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + list->qual[1] = qual[15]; + list->qual[2] = qual[16]; + + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + list->qual[5] = qual[17]; + list->qual[6] = qual[18]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap56_2; + + return(52); + } while(0); + + if(!qual[15]) return(0); + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[15] = 0; + memset(pt1,0,sizeof(Tetra)); + return(0); + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[1] = qual[15]; + list->qual[2] = qual[16]; + + if(!qual[9]) return(0); + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[9] = 0; + memset(pt1,0,sizeof(Tetra)); + return(0); + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[19] = 0; + memset(pt1,0,sizeof(Tetra)); + return(0); + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + list->qual[3] = qual[19]; + list->qual[4] = qual[20]; + + + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap56_5; + return(55); +} diff --git a/contrib/mmg3d/build/sources/simu68.c b/contrib/mmg3d/build/sources/simu68.c new file mode 100644 index 0000000000..f1114219a1 --- /dev/null +++ b/contrib/mmg3d/build/sources/simu68.c @@ -0,0 +1,1130 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* return 1-14 for config */ +int MMG_simu68(pMesh mesh,pSol sol,pList list,double crit) { + pTetra pt,pt1; + int ia,ib,s1,s2,s3,s4,s5,s6; + int iadr,*adja,k,adj,iel,iar; + short voy; + double caltab[2],qual[41]; + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + for(k=0 ; k<41 ; k++) + qual[k] = -1; + + /*find points of polygone*/ + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + /*printf("s1 %d s2 %d\n",s1,s2); + */iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + /* printf("tetra %d : %d %d %d %d\n",adj,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + */s3 = pt1->v[voy]; + /*printf("s3 %d \n",s3); + */iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu56: point s2 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + /*printf("tetra %d : %d %d %d %d\n",adj,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + */s4 = pt1->v[voy]; + /*printf("s4 %d\n",s4); + */iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s3) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s3) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s3) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu56_ani: point s4 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s6 = pt1->v[voy]; + + /*cas 1*/ + do { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[1] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[1] = caltab[0]; + qual[2] = caltab[1]; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[3] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[5] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + list->qual[5] = qual[5]; + list->qual[6] = qual[6]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + list->qual[7] = qual[7]; + list->qual[8] = qual[8]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_1; + + return(1); + } while(0); + + /*cas 2*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[3]) break; + else if(qual[3] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + } + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[9] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + list->qual[7] = qual[11]; + list->qual[8] = qual[12]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_2; + return(2); + } while(0); + + /*cas 3*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[13] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[15] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + list->qual[5] = qual[15]; + list->qual[6] = qual[16]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + list->qual[7] = qual[17]; + list->qual[8] = qual[18]; + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_3; + return(3); + } while(0); + + /*cas 4*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[11]) break; + else if(qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[7] = qual[11]; + list->qual[8] = qual[12]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[13] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[19] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + list->qual[5] = qual[19]; + list->qual[6] = qual[20]; + + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_4; + return(4); + } while(0); + + /*cas 5*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[9] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + if(!qual[11]) break; + else if(qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[7] = qual[11]; + list->qual[8] = qual[12]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[21] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[23] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[23] = caltab[0]; + qual[24] = caltab[1]; + list->qual[3] = qual[23]; + list->qual[4] = qual[24]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_5; + return(5); + } while(0); + + + /*cas 6*/ + do { + if(!qual[5]) break; + else if(qual[5] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[5] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + } + list->qual[5] = qual[5]; + list->qual[6] = qual[6]; + + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[7] = qual[7]; + list->qual[8] = qual[8]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[21] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + if(!qual[23]) break; + else if(qual[23] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[23] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[23] = caltab[0]; + qual[24] = caltab[1]; + } + list->qual[3] = qual[23]; + list->qual[4] = qual[24]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_6; + return(6); + } while(0); + + /*cas 7*/ + do { + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[1] = qual[7]; + list->qual[2] = qual[8]; + + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[7] = qual[17]; + list->qual[8] = qual[18]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[25] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + list->qual[3] = qual[25]; + list->qual[4] = qual[26]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[27] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + list->qual[5] = qual[27]; + list->qual[6] = qual[28]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_7; + return(7); + } while(0); + + /*cas 8*/ + do { + if(!qual[11]) break; + else if(qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[7] = qual[11]; + list->qual[8] = qual[12]; + + if(!qual[19]) break; + else if(qual[19] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[19] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + } + list->qual[5] = qual[19]; + list->qual[6] = qual[20]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[29] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[31] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + list->qual[3] = qual[31]; + list->qual[4] = qual[32]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_8; + return(8); + } while(0); + + /*cas 9*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[5] = qual[7]; + list->qual[6] = qual[8]; + + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[3] = qual[17]; + list->qual[4] = qual[18]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[33] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[33] = caltab[0]; + qual[34] = caltab[1]; + list->qual[7] = qual[33]; + list->qual[8] = qual[34]; + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_9; + return(9); + } while(0); + + /*cas 10*/ + do { + if(!qual[7]) break; + else if(qual[7] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[7] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[7] = qual[7]; + list->qual[8] = qual[8]; + + if(!qual[21]) break; + else if(qual[21] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[21] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + if(!qual[25]) break; + else if(qual[25] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[25] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[35] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + list->qual[3] = qual[35]; + list->qual[4] = qual[36]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_10; + return(10); + } while(0); + + /*cas 11*/ + do { + if(!qual[21]) break; + else if(qual[21] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[21] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + if(!qual[29]) break; + else if(qual[29] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[29] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[7] = qual[29]; + list->qual[8] = qual[30]; + + if(!qual[35]) break; + else if(qual[35] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + qual[35] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + } + list->qual[3] = qual[35]; + list->qual[4] = qual[36]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[37] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_11; + return(11); + } while(0); + + /*cas 12*/ + do { + if(!qual[17]) break; + else if(qual[17] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[7] = qual[17]; + list->qual[8] = qual[18]; + + if(!qual[27]) break; + else if(qual[27] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[27] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + } + list->qual[5] = qual[27]; + list->qual[6] = qual[28]; + + if(!qual[29]) break; + else if(qual[29] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[29] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + if(!qual[37]) break; + else if(qual[37] == -1){ + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[37] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[3] = qual[37]; + list->qual[4] = qual[38]; + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_12; + return(12); + } while(0); + + + /*cas 13*/ + do { + if(!qual[15]) break; + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[15] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[5] = qual[15]; + list->qual[6] = qual[16]; + + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[17] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[7] = qual[17]; + list->qual[8] = qual[18]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[29] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + if(!qual[31]) break; + else if(qual[31] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[31] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + } + list->qual[3] = qual[31]; + list->qual[4] = qual[32]; + + + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_13; + return(13); + } while(0); + + /*cas 14*/ + do { + if(!qual[11]) break; + else if(qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[11] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[5] = qual[11]; + list->qual[6] = qual[12]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[21] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[29] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + qual[39] = 0; + memset(pt1,0,sizeof(Tetra)); + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + list->qual[7] = qual[39]; + list->qual[8] = qual[40]; + /* set function ptr */ + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap68_14; + return(14); + } while(0); + + return(0); + +} diff --git a/contrib/mmg3d/build/sources/simu710.c b/contrib/mmg3d/build/sources/simu710.c new file mode 100644 index 0000000000..6fea0e70fe --- /dev/null +++ b/contrib/mmg3d/build/sources/simu710.c @@ -0,0 +1,4021 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* return 1-49 for config */ +int MMG_simu710(pMesh mesh,pSol sol,pList list,double crit) { + pTetra pt,pt1; + double qual[71],caltab[2]; + int ia,ib,s1,s2,s3,s4,s5,s6,s7; + int iadr,*adja,k,adj,iel,iar; + short voy; + + for(k=0 ; k<=71 ; k++) qual[k] = -1; + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + /*find points of polygone*/ + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu710: point s2 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + + s4 = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s3) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s3) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s3) { + k = MMG_idir[voy][2]; + } else { + printf("MMG_simu710: point s3 non existant %d \n",s3); + exit(0); + } + + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + + s5 = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s4) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s4) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s4) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu710: point s4 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s6 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s7 = pt1->v[voy]; + + /* printf("polygone : %d %d %d %d %d %d %d\n",s1,s2,s3,s4,s5,s6,s7); + */ + /*for(k=1 ; k<=7 ; k++) { + jel = list->tetra[k]/6; + pt1 =&mesh->tetra[jel]; + printf("tetra %d : %d %d %d %d\n",jel,pt1->v[0],pt1->v[1],pt1->v[2],pt1->v[3]); + }*/ + + /*cas 1*/ + do { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("cal 0 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[1] = 0; + break; + } + qual[1] = caltab[0]; + qual[2] = caltab[1]; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("caltab[0] 2 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[3] = 0; + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 4 %e %e \n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[5] = 0; + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + list->qual[5] = qual[5]; + list->qual[6] = qual[6]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[7] = 0; + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + list->qual[7] = qual[7]; + list->qual[8] = qual[8]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + list->qual[9] = qual[9]; + list->qual[10] = qual[10]; + + MMG_swpptr = MMG_swap710_1; + + return(71); + } while(0); + + /*cas 2*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[3]) break; + else if(qual[3] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[3] = 0; + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + } + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + if(!qual[5]) break; + else if(qual[5] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 5 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[5] = 0; + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + } + list->qual[5] = qual[5]; + list->qual[6] = qual[6]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[11] = 0; + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + list->qual[7] = qual[11]; + list->qual[8] = qual[12]; + + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + list->qual[9] = qual[13]; + list->qual[10] = qual[14]; + + MMG_swpptr = MMG_swap710_2; + return(72); + } while(0); + + /*cas 3*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[3]) break; + else if(qual[3] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[3] = 0; + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + } + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[5] = qual[13]; + list->qual[6] = qual[14]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[15] = 0; + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + list->qual[7] = qual[15]; + list->qual[8] = qual[16]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[17] = 0; + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + list->qual[9] = qual[17]; + list->qual[10] = qual[18]; + + MMG_swpptr = MMG_swap710_3; + return(73); + } while(0); + + /*cas 4*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[3]) break; + else if(qual[3] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[3] = 0; + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + } + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[17] = 0; + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[5] = qual[17]; + list->qual[6] = qual[18]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[19] = 0; + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + list->qual[7] = qual[19]; + list->qual[8] = qual[20]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + list->qual[9] = qual[21]; + list->qual[10] = qual[22]; + + MMG_swpptr = MMG_swap710_4; + return(74); + } while(0); + + /*cas 5*/ + do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[3]) break; + else if(qual[3] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 3 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[3] = 0; + break; + } + qual[3] = caltab[0]; + qual[4] = caltab[1]; + } + list->qual[3] = qual[3]; + list->qual[4] = qual[4]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[7] = qual[21]; + list->qual[8] = qual[22]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[23] = 0; + break; + } + qual[23] = caltab[0]; + qual[24] = caltab[1]; + list->qual[9] = qual[23]; + list->qual[10] = qual[24]; + + MMG_swpptr = MMG_swap710_5; + return(75); + } while(0); + + /*cas 6*/ + do { + if(!qual[5]) break; + else if(qual[5] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 4 %e %e \n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[5] = 0; + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + } + list->qual[1] = qual[5]; + list->qual[2] = qual[6]; + + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[7] = 0; + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[3] = qual[7]; + list->qual[4] = qual[8]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + list->qual[7] = qual[25]; + list->qual[8] = qual[26]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[27] = 0; + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + list->qual[9] = qual[27]; + list->qual[10] = qual[28]; + MMG_swpptr = MMG_swap710_6; + return(76); + } while(0); + + /*cas 7*/ + do { + if(!qual[5]) break; + else if(qual[5] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 5 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[5] = 0; + break; + } + qual[5] = caltab[0]; + qual[6] = caltab[1]; + } + list->qual[1] = qual[5]; + list->qual[2] = qual[6]; + + if(!qual[11]) break; + else if (qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[11] = 0; + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[3] = qual[11]; + list->qual[4] = qual[12]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[5] = qual[13]; + list->qual[6] = qual[14]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[7] = qual[25]; + list->qual[8] = qual[26]; + + if(!qual[27]) break; + else if(qual[27] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[27] = 0; + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + } + list->qual[9] = qual[27]; + list->qual[10] = qual[28]; + MMG_swpptr = MMG_swap710_7; + return(77); + } while(0); + + /*cas 8*/ + do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[15]) break; + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[15] = 0; + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[3] = qual[15]; + list->qual[4] = qual[16]; + + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[17] = 0; + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[5] = qual[17]; + list->qual[6] = qual[18]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[7] = qual[25]; + list->qual[8] = qual[26]; + + if(!qual[27]) break; + else if(qual[27] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[27] = 0; + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + } + list->qual[9] = qual[27]; + list->qual[10] = qual[28]; + MMG_swpptr = MMG_swap710_8; + return(78); + } while(0); + + /*cas 9*/ + do { + if(!qual[17]) break; + else if(qual[17] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 17 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[17] = 0; + break; + } + qual[17] = caltab[0]; + qual[18] = caltab[1]; + } + list->qual[1] = qual[17]; + list->qual[2] = qual[18]; + + if(!qual[19]) break; + else if(qual[19] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[19] = 0; + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + } + list->qual[3] = qual[19]; + list->qual[4] = qual[20]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[5] = qual[21]; + list->qual[6] = qual[22]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[7] = qual[25]; + list->qual[8] = qual[26]; + + if(!qual[27]) break; + else if(qual[27] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[27] = 0; + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + } + list->qual[9] = qual[27]; + list->qual[10] = qual[28]; + MMG_swpptr = MMG_swap710_9; + return(79); + } while(0); + + /*cas 10*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[23]) break; + else if(qual[23] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[23] = 0; + break; + } + qual[23] = caltab[0]; + qual[24] = caltab[1]; + } + list->qual[5] = qual[23]; + list->qual[6] = qual[24]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[7] = qual[25]; + list->qual[8] = qual[26]; + + if(!qual[27]) break; + else if(qual[27] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 12 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[27] = 0; + break; + } + qual[27] = caltab[0]; + qual[28] = caltab[1]; + } + list->qual[9] = qual[27]; + list->qual[10] = qual[28]; + + MMG_swpptr = MMG_swap710_10; + memset(pt1,0,sizeof(Tetra)); + return(80); + } while(0); + + /*cas 11*/ + do { + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[1] = qual[25]; + list->qual[2] = qual[26]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + list->qual[3] = qual[29]; + list->qual[4] = qual[30]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[31] = 0; + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + list->qual[5] = qual[31]; + list->qual[6] = qual[32]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[33] = 0; + break; + } + qual[33] = caltab[0]; + qual[34] = caltab[1]; + list->qual[7] = qual[33]; + list->qual[8] = qual[34]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[35] = 0; + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + list->qual[9] = qual[35]; + list->qual[10] = qual[36]; + + memset(pt1,0,sizeof(Tetra)); + MMG_swpptr = MMG_swap710_11; + return(81); + } while(0); + + /*cas 12*/ + do { + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + if(!qual[31]) break; + else if(qual[31] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[31] = 0; + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + } + list->qual[3] = qual[31]; + list->qual[4] = qual[32]; + + if(!qual[33]) break; + else if(qual[33] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[33] = 0; + break; + } + qual[33] = caltab[0]; + qual[34] = caltab[1]; + } + list->qual[5] = qual[33]; + list->qual[6] = qual[34]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + list->qual[7] = qual[37]; + list->qual[8] = qual[38]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[39] = 0; + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + list->qual[9] = qual[39]; + list->qual[10] = qual[40]; + + MMG_swpptr = MMG_swap710_12; + memset(pt1,0,sizeof(Tetra)); + return(82); + + } while(0); + + /*cas 13*/ + do { + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + if(!qual[31]) break; + else if(qual[31] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[31] = 0; + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + } + list->qual[3] = qual[31]; + list->qual[4] = qual[32]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[41] = 0; + break; + } + qual[41] = caltab[0]; + qual[42] = caltab[1]; + list->qual[7] = qual[41]; + list->qual[8] = qual[42]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[43] = 0; + break; + } + qual[43] = caltab[0]; + qual[44] = caltab[1]; + list->qual[9] = qual[43]; + list->qual[10] = qual[44]; + MMG_swpptr = MMG_swap710_13; + memset(pt1,0,sizeof(Tetra)); + return(84); + } while(0); + + /*cas 15*/ + do { + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[3] = qual[25]; + list->qual[4] = qual[26]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[5] = qual[29]; + list->qual[6] = qual[30]; + + if(!qual[31]) break; + else if(qual[31] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[31] = 0; + break; + } + qual[31] = caltab[0]; + qual[32] = caltab[1]; + } + list->qual[7] = qual[31]; + list->qual[8] = qual[32]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[47] = 0; + break; + } + qual[47] = caltab[0]; + qual[48] = caltab[1]; + list->qual[9] = qual[47]; + list->qual[10] = qual[48]; + + MMG_swpptr = MMG_swap710_15; + memset(pt1,0,sizeof(Tetra)); + return(85); + } while(0); + + /*cas 16*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[3] = qual[25]; + list->qual[4] = qual[26]; + + if(!qual[33]) break; + else if(qual[33] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[33] = 0; + break; + } + qual[33] = caltab[0]; + qual[34] = caltab[1]; + } + list->qual[5] = qual[33]; + list->qual[6] = qual[34]; + + if(!qual[35]) break; + else if(qual[35] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[35] = 0; + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + } + list->qual[7] = qual[35]; + list->qual[8] = qual[36]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[49] = 0; + break; + } + qual[49] = caltab[0]; + qual[50] = caltab[1]; + list->qual[9] = qual[49]; + list->qual[10] = qual[50]; + + MMG_swpptr = MMG_swap710_16; + memset(pt1,0,sizeof(Tetra)); + return(86); + } while(0); + + /*cas 17*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[33]) break; + else if(qual[33] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + ////printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[33] = 0; + break; + } + qual[33] = caltab[0]; + qual[34] = caltab[1]; + } + list->qual[3] = qual[33]; + list->qual[4] = qual[34]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[39]) break; + else if(qual[39] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[39] = 0; + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + } + list->qual[7] = qual[39]; + list->qual[8] = qual[40]; + + if(!qual[49]) break; + else if(qual[49] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[49] = 0; + break; + } + qual[49] = caltab[0]; + qual[50] = caltab[1]; + } + list->qual[9] = qual[49]; + list->qual[10] = qual[50]; + + MMG_swpptr = MMG_swap710_17; + memset(pt1,0,sizeof(Tetra)); + return(87); + } while(0); + + /*cas 18*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[3] = qual[37]; + list->qual[4] = qual[38]; + + if(!qual[41]) break; + else if(qual[41] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[41] = 0; + break; + } + qual[41] = caltab[0]; + qual[42] = caltab[1]; + } + list->qual[5] = qual[41]; + list->qual[6] = qual[42]; + + if(!qual[43]) break; + else if(qual[43] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[43] = 0; + break; + } + qual[43] = caltab[0]; + qual[44] = caltab[1]; + } + list->qual[7] = qual[43]; + list->qual[8] = qual[44]; + + if(!qual[49]) break; + else if(qual[49] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[49] = 0; + break; + } + qual[49] = caltab[0]; + qual[50] = caltab[1]; + } + list->qual[9] = qual[49]; + list->qual[10] = qual[50]; + + MMG_swpptr = MMG_swap710_18; + memset(pt1,0,sizeof(Tetra)); + return(88); + } while(0); + + /*cas 19*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[41]) break; + else if(qual[41] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[41] = 0; + break; + } + qual[41] = caltab[0]; + qual[42] = caltab[1]; + } + list->qual[5] = qual[41]; + list->qual[6] = qual[42]; + + if(!qual[45]) break; + else if(qual[45] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[45] = 0; + break; + } + qual[45] = caltab[0]; + qual[46] = caltab[1]; + } + list->qual[7] = qual[45]; + list->qual[8] = qual[46]; + + if(!qual[49]) break; + else if(qual[49] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[49] = 0; + break; + } + qual[49] = caltab[0]; + qual[50] = caltab[1]; + } + list->qual[9] = qual[49]; + list->qual[10] = qual[50]; + + + MMG_swpptr = MMG_swap710_19; + memset(pt1,0,sizeof(Tetra)); + return(89); + } while(0); + + /*cas 20*/ + do { + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[1] = qual[9]; + list->qual[2] = qual[10]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + if(!qual[47]) break; + else if(qual[47] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[47] = 0; + break; + } + qual[47] = caltab[0]; + qual[48] = caltab[1]; + } + list->qual[7] = qual[47]; + list->qual[8] = qual[48]; + if(!qual[49]) break; + else if(qual[49] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[49] = 0; + break; + } + qual[49] = caltab[0]; + qual[50] = caltab[1]; + } + list->qual[9] = qual[49]; + list->qual[10] = qual[50]; + + MMG_swpptr = MMG_swap710_20; + memset(pt1,0,sizeof(Tetra)); + return(90); + } while(0); + +/*cas 21*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[3] = qual[37]; + list->qual[4] = qual[38]; + + if(!qual[43]) break; + else if(qual[43] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[43] = 0; + break; + } + qual[43] = caltab[0]; + qual[44] = caltab[1]; + } + list->qual[5] = qual[43]; + list->qual[6] = qual[44]; + + if(!qual[69]) break; + else if(qual[69] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[69] = 0; + break; + } + qual[69] = caltab[0]; + qual[70] = caltab[1]; + } + list->qual[7] = qual[69]; + list->qual[8] = qual[70]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[51] = 0; + break; + } + qual[51] = caltab[0]; + qual[52] = caltab[1]; + list->qual[9] = qual[51]; + list->qual[10] = qual[52]; + + MMG_swpptr = MMG_swap710_21; + memset(pt1,0,sizeof(Tetra)); + return(91); +} while(0); + +/*cas 22*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[45]) break; + else if(qual[45] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[45] = 0; + break; + } + qual[45] = caltab[0]; + qual[46] = caltab[1]; + } + list->qual[5] = qual[45]; + list->qual[6] = qual[46]; + + if(!qual[51]) break; + else if(qual[51] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[51] = 0; + break; + } + qual[51] = caltab[0]; + qual[52] = caltab[1]; + } + list->qual[7] = qual[51]; + list->qual[8] = qual[52]; + + if(!qual[69]) break; + else if(qual[69] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[69] = 0; + break; + } + qual[69] = caltab[0]; + qual[70] = caltab[1]; + } + list->qual[9] = qual[69]; + list->qual[10] = qual[70]; + + MMG_swpptr = MMG_swap710_22; + memset(pt1,0,sizeof(Tetra)); + return(92); +} while(0); + +/*cas 23*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[19]) break; + else if(qual[19] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[19] = 0; + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + } + list->qual[3] = qual[19]; + list->qual[4] = qual[20]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[5] = qual[21]; + list->qual[6] = qual[22]; + + if(!qual[51]) break; + else if(qual[51] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[51] = 0; + break; + } + qual[51] = caltab[0]; + qual[52] = caltab[1]; + } + list->qual[7] = qual[51]; + list->qual[8] = qual[52]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[53] = 0; + break; + } + qual[53] = caltab[0]; + qual[54] = caltab[1]; + + list->qual[9] = qual[53]; + list->qual[10] = qual[54]; + + MMG_swpptr = MMG_swap710_23; + memset(pt1,0,sizeof(Tetra)); + return(93); +} while(0); + +/*cas 24*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + if(!qual[15]) break; + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[15] = 0; + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[5] = qual[15]; + list->qual[6] = qual[16]; + + if(!qual[51]) break; + else if(qual[51] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[51] = 0; + break; + } + qual[51] = caltab[0]; + qual[52] = caltab[1]; + } + list->qual[7] = qual[51]; + list->qual[8] = qual[52]; + + if(!qual[53]) break; + else if(qual[53] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[53] = 0; + break; + } + qual[53] = caltab[0]; + qual[54] = caltab[1]; + } + list->qual[9] = qual[53]; + list->qual[10] = qual[54]; + + MMG_swpptr = MMG_swap710_24; + memset(pt1,0,sizeof(Tetra)); + return(94); +} while(0); + +/*cas 25*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[51]) break; + else if(qual[51] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[51] = 0; + break; + } + qual[51] = caltab[0]; + qual[52] = caltab[1]; + } + list->qual[7] = qual[51]; + list->qual[8] = qual[52]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[55] = 0; + break; + } + qual[55] = caltab[0]; + qual[56] = caltab[1]; + + list->qual[9] = qual[55]; + list->qual[10] = qual[56]; + + MMG_swpptr = MMG_swap710_25; + memset(pt1,0,sizeof(Tetra)); + return(95); +} while(0); + +/*cas 26*/ +do { + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[1] = qual[29]; + list->qual[2] = qual[30]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[3] = qual[37]; + list->qual[4] = qual[38]; + + if(!qual[43]) break; + else if(qual[43] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[43] = 0; + break; + } + qual[43] = caltab[0]; + qual[44] = caltab[1]; + } + list->qual[5] = qual[43]; + list->qual[6] = qual[44]; + + if(!qual[69]) break; + else if(qual[69] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[69] = 0; + break; + } + qual[69] = caltab[0]; + qual[70] = caltab[1]; + } + list->qual[7] = qual[69]; + list->qual[8] = qual[70]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[57] = 0; + break; + } + qual[57] = caltab[0]; + qual[58] = caltab[1]; + list->qual[9] = qual[57]; + list->qual[10] = qual[58]; + + MMG_swpptr = MMG_swap710_26; + memset(pt1,0,sizeof(Tetra)); + return(96); +} while(0); + +/*cas 27*/ +do { + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[1] = qual[21]; + list->qual[2] = qual[22]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[3] = qual[29]; + list->qual[4] = qual[30]; + + if(!qual[45]) break; + else if(qual[45] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[45] = 0; + break; + } + qual[45] = caltab[0]; + qual[46] = caltab[1]; + } + list->qual[5] = qual[45]; + list->qual[6] = qual[46]; + + if(!qual[57]) break; + else if(qual[57] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[57] = 0; + break; + } + qual[57] = caltab[0]; + qual[58] = caltab[1]; + } + list->qual[7] = qual[57]; + list->qual[8] = qual[58]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[69] = 0; + break; + } + qual[69] = caltab[0]; + qual[70] = caltab[1]; + list->qual[9] = qual[69]; + list->qual[10] = qual[70]; + MMG_swpptr = MMG_swap710_27; + memset(pt1,0,sizeof(Tetra)); + return(97); +} while(0); + +/*cas 28*/ +do { + if(!qual[19]) break; + else if(qual[19] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[19] = 0; + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + } + list->qual[1] = qual[19]; + list->qual[2] = qual[20]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[5] = qual[29]; + list->qual[6] = qual[30]; + + if(!qual[53]) break; + else if(qual[53] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[53] = 0; + break; + } + qual[53] = caltab[0]; + qual[54] = caltab[1]; + } + list->qual[7] = qual[53]; + list->qual[8] = qual[54]; + + if(!qual[57]) break; + else if(qual[57] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[57] = 0; + break; + } + qual[57] = caltab[0]; + qual[58] = caltab[1]; + } + list->qual[9] = qual[57]; + list->qual[10] = qual[58]; + + MMG_swpptr = MMG_swap710_28; + memset(pt1,0,sizeof(Tetra)); + return(98); +} while(0); + +/*cas 29*/ +do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[15]) break; + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[15] = 0; + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[3] = qual[15]; + list->qual[4] = qual[16]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[5] = qual[29]; + list->qual[6] = qual[30]; + + if(!qual[53]) break; + else if(qual[53] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[53] = 0; + break; + } + qual[53] = caltab[0]; + qual[54] = caltab[1]; + } + list->qual[7] = qual[53]; + list->qual[8] = qual[54]; + + if(!qual[57]) break; + else if(qual[57] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[57] = 0; + break; + } + qual[57] = caltab[0]; + qual[58] = caltab[1]; + } + list->qual[9] = qual[57]; + list->qual[10] = qual[58]; + + MMG_swpptr = MMG_swap710_29; + memset(pt1,0,sizeof(Tetra)); + return(99); +} while(0); + +/*cas 30*/ +do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[3] = qual[29]; + list->qual[4] = qual[30]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[55]) break; + else if(qual[55] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[55] = 0; + break; + } + qual[55] = caltab[0]; + qual[56] = caltab[1]; + } + list->qual[8] = qual[55]; + list->qual[9] = qual[56]; + + if(!qual[57]) break; + else if(qual[57] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[57] = 0; + break; + } + qual[57] = caltab[0]; + qual[58] = caltab[1]; + } + list->qual[9] = qual[57]; + list->qual[10] = qual[58]; + + MMG_swpptr = MMG_swap710_30; + memset(pt1,0,sizeof(Tetra)); + return(100); +} while(0); + +/*cas 31*/ +do { + if(!qual[19]) break; + else if(qual[19] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 19 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[19] = 0; + break; + } + qual[19] = caltab[0]; + qual[20] = caltab[1]; + } + list->qual[1] = qual[19]; + list->qual[2] = qual[20]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[3] = qual[21]; + list->qual[4] = qual[22]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[7] = qual[29]; + list->qual[8] = qual[30]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[59] = 0; + break; + } + qual[59] = caltab[0]; + qual[60] = caltab[1]; + list->qual[9] = qual[59]; + list->qual[10] = qual[60]; + + MMG_swpptr = MMG_swap710_31; + memset(pt1,0,sizeof(Tetra)); + return(101); +} while(0); + +/*cas 32*/ +do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[15]) break; + else if(qual[15] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 15 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[15] = 0; + break; + } + qual[15] = caltab[0]; + qual[16] = caltab[1]; + } + list->qual[3] = qual[15]; + list->qual[4] = qual[16]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[7] = qual[29]; + list->qual[8] = qual[30]; + + if(!qual[59]) break; + else if(qual[59] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[59] = 0; + break; + } + qual[59] = caltab[0]; + qual[60] = caltab[1]; + } + list->qual[9] = qual[59]; + list->qual[10] = qual[60]; + + MMG_swpptr = MMG_swap710_32; + memset(pt1,0,sizeof(Tetra)); + return(102); +} while(0); + +/*cas 33*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[7] = 0; + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[3] = qual[7]; + list->qual[4] = qual[8]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[5] = qual[9]; + list->qual[6] = qual[10]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[7] = qual[37]; + list->qual[8] = qual[38]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[61] = 0; + break; + } + qual[61] = caltab[0]; + qual[62] = caltab[1]; + list->qual[9] = qual[61]; + list->qual[10] = qual[62]; + + MMG_swpptr = MMG_swap710_33; + memset(pt1,0,sizeof(Tetra)); + return(103); +} while(0); + +/*cas 34*/ +do { + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[7] = 0; + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[1] = qual[7]; + list->qual[2] = qual[8]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[3] = qual[9]; + list->qual[4] = qual[10]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[39]) break; + else if(qual[39] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[39] = 0; + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + } + list->qual[7] = qual[39]; + list->qual[8] = qual[40]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[63] = 0; + break; + } + qual[63] = caltab[0]; + qual[64] = caltab[1]; + list->qual[9] = qual[63]; + list->qual[10] = qual[64]; + + MMG_swpptr = MMG_swap710_34; + memset(pt1,0,sizeof(Tetra)); + return(104); +} while(0); + +/*cas 35*/ +do { + if(!qual[7]) break; + else if(qual[7] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 6 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[7] = 0; + break; + } + qual[7] = caltab[0]; + qual[8] = caltab[1]; + } + list->qual[1] = qual[7]; + list->qual[2] = qual[8]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("cal 8 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[3] = qual[9]; + list->qual[4] = qual[10]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + if(!qual[35]) break; + else if(qual[35] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[35] = 0; + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + } + list->qual[7] = qual[35]; + list->qual[8] = qual[36]; + + if(!qual[63]) break; + else if(qual[63] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[63] = 0; + break; + } + qual[63] = caltab[0]; + qual[64] = caltab[1]; + } + list->qual[9] = qual[63]; + list->qual[10] = qual[64]; + + MMG_swpptr = MMG_swap710_35; + memset(pt1,0,sizeof(Tetra)); + return(105); +} while(0); + +/*cas 36*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[11]) break; + else if (qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[11] = 0; + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[3] = qual[11]; + list->qual[4] = qual[12]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[5] = qual[13]; + list->qual[6] = qual[14]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[7] = qual[37]; + list->qual[8] = qual[38]; + + if(!qual[61]) break; + else if(qual[61] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[61] = 0; + break; + } + qual[61] = caltab[0]; + qual[62] = caltab[1]; + } + list->qual[9] = qual[61]; + list->qual[10] = qual[62]; + + MMG_swpptr = MMG_swap710_36; + memset(pt1,0,sizeof(Tetra)); + return(106); +} while(0); + +/*cas 37*/ +do { + if(!qual[11]) break; + else if (qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[11] = 0; + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[1] = qual[11]; + list->qual[2] = qual[12]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[39]) break; + else if(qual[39] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[39] = 0; + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + } + list->qual[7] = qual[39]; + list->qual[8] = qual[40]; + + if(!qual[63]) break; + else if(qual[63] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[63] = 0; + break; + } + qual[63] = caltab[0]; + qual[64] = caltab[1]; + } + list->qual[9] = qual[63]; + list->qual[10] = qual[64]; + + MMG_swpptr = MMG_swap710_37; + memset(pt1,0,sizeof(Tetra)); + return(107); +} while(0); + +/*cas 38*/ +do { + if(!qual[11]) break; + else if (qual[11] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 11 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[11] = 0; + break; + } + qual[11] = caltab[0]; + qual[12] = caltab[1]; + } + list->qual[1] = qual[11]; + list->qual[2] = qual[12]; + + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[3] = qual[13]; + list->qual[4] = qual[14]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[5] = qual[25]; + list->qual[6] = qual[26]; + + if(!qual[35]) break; + else if(qual[35] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[35] = 0; + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + } + list->qual[7] = qual[35]; + list->qual[8] = qual[36]; + + if(!qual[63]) break; + else if(qual[63] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[63] = 0; + break; + } + qual[63] = caltab[0]; + qual[64] = caltab[1]; + } + list->qual[9] = qual[63]; + list->qual[10] = qual[64]; + + MMG_swpptr = MMG_swap710_38; + memset(pt1,0,sizeof(Tetra)); + return(108); +} while(0); + +/*cas 39*/ +do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[3] = qual[29]; + list->qual[4] = qual[30]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[39]) break; + else if(qual[39] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[39] = 0; + break; + } + qual[39] = caltab[0]; + qual[40] = caltab[1]; + } + list->qual[7] = qual[39]; + list->qual[8] = qual[40]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[65] = 0; + break; + } + qual[65] = caltab[0]; + qual[66] = caltab[1]; + list->qual[9] = qual[65]; + list->qual[10] = qual[66]; + + MMG_swpptr = MMG_swap710_39; + memset(pt1,0,sizeof(Tetra)); + return(109); +} while(0); + +/*cas 40*/ +do { + if(!qual[13]) break; + else if(qual[13] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s5; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 13 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[13] = 0; + break; + } + qual[13] = caltab[0]; + qual[14] = caltab[1]; + } + list->qual[1] = qual[13]; + list->qual[2] = qual[14]; + + if(!qual[25]) break; + else if(qual[25] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[25] = 0; + break; + } + qual[25] = caltab[0]; + qual[26] = caltab[1]; + } + list->qual[3] = qual[25]; + list->qual[4] = qual[26]; + + if(!qual[29]) break; + else if(qual[29] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[29] = 0; + break; + } + qual[29] = caltab[0]; + qual[30] = caltab[1]; + } + list->qual[5] = qual[29]; + list->qual[6] = qual[30]; + + if(!qual[35]) break; + else if(qual[35] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[35] = 0; + break; + } + qual[35] = caltab[0]; + qual[36] = caltab[1]; + } + list->qual[7] = qual[35]; + list->qual[8] = qual[36]; + + if(!qual[65]) break; + else if(qual[65] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[65] = 0; + break; + } + qual[65] = caltab[0]; + qual[66] = caltab[1]; + } + list->qual[9] = qual[65]; + list->qual[10] = qual[66]; + + MMG_swpptr = MMG_swap710_40; + memset(pt1,0,sizeof(Tetra)); + return(110); +} while(0); + +/*cas 41*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[3] = qual[9]; + list->qual[4] = qual[10]; + + if(!qual[21]) break; + else if(qual[21] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s4; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 21 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[21] = 0; + break; + } + qual[21] = caltab[0]; + qual[22] = caltab[1]; + } + list->qual[5] = qual[21]; + list->qual[6] = qual[22]; + + if(!qual[45]) break; + else if(qual[45] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[45] = 0; + break; + } + qual[45] = caltab[0]; + qual[46] = caltab[1]; + } + list->qual[7] = qual[45]; + list->qual[8] = qual[46]; + + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[67] = 0; + break; + } + qual[67] = caltab[0]; + qual[68] = caltab[1]; + list->qual[9] = qual[67]; + list->qual[10] = qual[68]; + + MMG_swpptr = MMG_swap710_41; + memset(pt1,0,sizeof(Tetra)); + return(111); +} while(0); + +/*cas 42*/ +do { + if(!qual[1]) break; + list->qual[1] = qual[1]; + list->qual[2] = qual[2]; + + if(!qual[9]) break; + else if(qual[9] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s6; + pt1->v[3] = s7; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)){ + //printf("2:cal 9 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[9] = 0; + break; + } + qual[9] = caltab[0]; + qual[10] = caltab[1]; + } + list->qual[3] = qual[9]; + list->qual[4] = qual[10]; + + if(!qual[37]) break; + else if(qual[37] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[37] = 0; + break; + } + qual[37] = caltab[0]; + qual[38] = caltab[1]; + } + list->qual[5] = qual[37]; + list->qual[6] = qual[38]; + + if(!qual[43]) break; + else if(qual[43] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[43] = 0; + break; + } + qual[43] = caltab[0]; + qual[44] = caltab[1]; + } + list->qual[7] = qual[43]; + list->qual[8] = qual[44]; + + if(!qual[67]) break; + else if(qual[67] == -1) { + pt1 = &mesh->tetra[0]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s6; + if(!MMG_caltet2(mesh,sol,0,ib,crit,caltab)) { + //printf("2:cal 25 %e %e\n",caltab[0],MMG_voltet(mesh,0)); + memset(pt1,0,sizeof(Tetra)); + qual[67] = 0; + break; + } + qual[67] = caltab[0]; + qual[68] = caltab[1]; + } + list->qual[9] = qual[67]; + list->qual[10] = qual[68]; + + MMG_swpptr = MMG_swap710_42; + memset(pt1,0,sizeof(Tetra)); + return(112); +} while(0); + + return(0); +} diff --git a/contrib/mmg3d/build/sources/solmap.c b/contrib/mmg3d/build/sources/solmap.c new file mode 100644 index 0000000000..16e05cefc3 --- /dev/null +++ b/contrib/mmg3d/build/sources/solmap.c @@ -0,0 +1,208 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +static int MMG_inxtt[5] = {0,1,2,0,1}; + + +/* compute iso size map */ +int MMG_doSol(pMesh mesh,pSol sol) { + pTetra pt; + pTria ptt; + pPoint p1,p2; + double ux,uy,uz,dd; + int i,k,ia,ib,ipa,ipb; + + /* memory alloc */ + sol->np = mesh->np; + sol->npfixe = mesh->npfixe; + sol->npmax = mesh->npmax; + sol->offset = 1; + + if ( !MMG_zaldy3(sol) ) return(0); + /* boundary edges */ + for (k=1; k<=mesh->nt; k++) { + ptt = &mesh->tria[k]; + if ( !ptt->v[0] ) continue; + + for (i=0; i<3; i++) { + ib = MMG_inxtt[i+1]; + ipa = ptt->v[i]; + ipb = ptt->v[ib]; + p1 = &mesh->point[ipa]; + p2 = &mesh->point[ipb]; + + ux = p1->c[0] - p2->c[0]; + uy = p1->c[1] - p2->c[1]; + uz = p1->c[2] - p2->c[2]; + dd = sqrt(ux*ux + uy*uy + uz*uz); + + sol->met[ipa] += dd; + p1->mark++; + sol->met[ipb] += dd; + p2->mark++; + } + } + + /* internal edges */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !pt->v[0] ) continue; + + /* internal edges */ + for (i=0; i<6; i++) { + ia = MMG_iare[i][0]; + ib = MMG_iare[i][1]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + p1 = &mesh->point[ipa]; + p2 = &mesh->point[ipb]; + + ux = p1->c[0] - p2->c[0]; + uy = p1->c[1] - p2->c[1]; + uz = p1->c[2] - p2->c[2]; + dd = sqrt(ux*ux + uy*uy + uz*uz); + + //if ( !(p1->tag & M_BDRY) ) { + sol->met[ipa] += dd; + p1->mark++; + //} + //if ( !(p2->tag & M_BDRY) ) { + sol->met[ipb] += dd; + p2->mark++; + //} + } + } + + /* vertex size */ + sol->hmin = 1.e20; + sol->hmax = 0.0; + for (k=1; k<=mesh->np; k++) { + p1 = &mesh->point[k]; + if ( !p1->mark ) continue; + + sol->met[k] = sol->met[k] / (double)p1->mark; + + if ( sol->met[k] < sol->hmin ) + sol->hmin = sol->met[k]; + else if ( sol->met[k] > sol->hmax ) + sol->hmax = sol->met[k]; + + p1->mark = 0; + } + + if ( mesh->info.imprim < -4 ) + fprintf(stdout," HMIN %f HMAX %f\n",sol->hmin,sol->hmax); + + /*compute quality*/ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( pt->v[0] ) + pt->qual = MMG_caltet(mesh,sol,k); + else + pt->qual = 0.0; + } + + return(1); +} + +/* interpol iso/aniso size map */ +int MMG_computeMetric(pMesh mesh,pSol sol,int ip,double * coor) { + pTetra pt; + pPoint ppt; + double cb[4]; + double dma[6],mai[6],mi[6]; + double *mp,*ma; + int ktet,i,k,base,iadr,ia; + + ppt = &mesh->point[ip]; + base = ++mesh->mark; + ktet = MMG_loctet(mesh,ppt->tmp,base,coor,cb); + if(!ktet) return(-1); + assert(ktet < mesh->ne + 1); + pt = &mesh->tetra[ktet]; + + if ( sol->offset == 1 ) { + sol->met[ip] = cb[0] * sol->metold[pt->v[0]]; + + for(k = 1 ; k < 4 ; k++) { + sol->met[ip] += cb[k] * sol->metold[pt->v[k]]; + } + } else { + iadr = (ip-1)*sol->offset + 1; + mp = &sol->met[iadr]; + + for (i=0; i<6; i++) mi[i] = 0; + + for(k = 0 ; k < 4 ; k++) { + ia = pt->v[k]; + iadr = (ia-1)*sol->offset + 1; + ma = &sol->met[iadr]; + for (i=0; i<6; i++) { + dma[i] = ma[i]; + } + + if ( !MMG_invmat(dma,mai) ) { + fprintf(stderr," ## INVALID METRIC.\n"); + return(0); + } + + for (i=0; i<6; i++) + mi[i] += cb[k]*mai[i]; + } + + if ( !MMG_invmat(mi,mai) ) { + fprintf(stderr," ## INVALID METRIC.\n"); + return(0); + } + + for (i=0; i<6; i++) mp[i] = mai[i]; + + } + + return(1); +} + diff --git a/contrib/mmg3d/build/sources/spledg.c b/contrib/mmg3d/build/sources/spledg.c new file mode 100644 index 0000000000..de9965df9f --- /dev/null +++ b/contrib/mmg3d/build/sources/spledg.c @@ -0,0 +1,132 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define QCOEF 0.995 + + +int MMG_spledg(pMesh mesh,pSol sol,pQueue queue,pList list,int lon,double crit,double declic) { + pTetra pt,pt0,pt1; + pPoint pa,pb; + double cal; + double *ca,*cb,c[3],*ma,*mb,*mip,mp[6]; + int l,ipa,ipb,ip,jel,na,nbt,iel,iar,ret,iadr; + short ia,ib; + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + ia = MMG_iare[iar][0]; + ib = MMG_iare[iar][1]; + + pt = &mesh->tetra[iel]; + ipa = pt->v[ia]; + ipb = pt->v[ib]; + pa = &mesh->point[ipa]; + pb = &mesh->point[ipb]; + + ca = &mesh->point[ipa].c[0]; + cb = &mesh->point[ipb].c[0]; + + iadr = (ipa-1)*sol->offset + 1; + ma = &sol->met[iadr]; + + iadr = (ipb-1)*sol->offset + 1; + mb = &sol->met[iadr]; + + /* metric interpolation */ + if ( !MMG_interp(ma,mb,mp,0.5) ) return(0); + + c[0] = 0.5*(ca[0] + cb[0]); + c[1] = 0.5*(ca[1] + cb[1]); + c[2] = 0.5*(ca[2] + cb[2]); + ip = MMG_newPt(mesh,c); + if ( ip < 1 ) return(0); + iadr = (ip-1)*sol->offset + 1; + mip = &sol->met[iadr]; + memcpy(mip,mp,sol->offset*sizeof(double)); + + /* eval coquille */ + pt0 = &mesh->tetra[0]; + nbt = 0; + for (l=1; l<=lon; l++) { + jel = list->tetra[l] / 6; + na = list->tetra[l] % 6; + pt1 = &mesh->tetra[jel]; + + memcpy(pt0->v,pt1->v,4*sizeof(int)); + ipb = MMG_iare[na][0]; + pt0->v[ipb] = ip; + cal = MMG_caltet(mesh,sol,0); + if ( cal > crit ) { + MMG_delPt(mesh,ip); + return(0); + } + + memcpy(pt0->v,pt1->v,4*sizeof(int)); + ipb = MMG_iare[na][1]; + pt0->v[ipb] = ip; + cal = MMG_caltet(mesh,sol,0); + if ( cal > crit ) { + MMG_delPt(mesh,ip); + return(0); + } + } + + /* update */ + for (l=1; l<=lon; l++) { + list->tetra[l] = list->tetra[l] / 6; + mesh->tetra[list->tetra[l]].mark = mesh->mark; + } + ret = MMG_delons(mesh,sol,queue,ip,list,lon,declic); + if ( ret <= 0 ) { + MMG_delPt(mesh,ip); + return(0); + } + else { + return(ip); + } +} + diff --git a/contrib/mmg3d/build/sources/sproto.h b/contrib/mmg3d/build/sources/sproto.h new file mode 100644 index 0000000000..178623047f --- /dev/null +++ b/contrib/mmg3d/build/sources/sproto.h @@ -0,0 +1,240 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ + +int MMG_cassar(pMesh mesh,pSol sol,int ipa,int ipb,float t); +int MMG_analar(pMesh ,pSol ,pBucket ,int *,int *,int *,int *); +int MMG_boulep(pMesh ,int ,int ,pList ); +int MMG_bouleg(pMesh ,int ,int ,pList ); +int MMG_coquil(pMesh ,int ,int ,pList ); +int MMG_cendel(pMesh ,pSol ,float ,int ); +int MMG_spledg(pMesh ,pSol ,pQueue ,pList ,int ,float ,float ); + +/* delaunay */ +int MMG_correction(pMesh ,int ,pList ,int ,int ,char ); +int MMG_delone(pMesh ,pSol ,int ,pList ,int ); +int MMG_delons(pMesh ,pSol ,pQueue ,int ,pList ,int ,float ); +int MMG_cenrad_ani(pMesh ,pSol ,int ,double *,double *,double *); +int MMG_cenrad_iso(pMesh ,pSol ,int ,double *,double *); + +int MMG_colpoi(pMesh ,pSol ,int ,int ,int ,float ); + +/* hash */ +int MMG_hashTetra(pMesh ); +int MMG_hashEdge(pMesh ,pHedge ,int ,int ,int *); +int MMG_inEdge(pHedge ,int *,int *,int *); +int MMG_markBdry(pMesh ); + +/* inout */ +int MMG_loadMesh(pMesh ,char *); +int MMG_loadSol(pSol ,char *,int ); +int MMG_loadVect(pMesh ,char *,int ); +int MMG_saveMesh(pMesh ,char *); +int MMG_saveSol(pMesh ,pSol ,char *); +int MMG_saveVect(pMesh ,char *); + +int MMG_loctet(pMesh ,int ,int ,double *,double *); +int MMG_computeMetric(pMesh ,pSol ,int ,double * ); + +/* scale */ +int MMG_doSol(pMesh ,pSol ); +int MMG_scaleMesh(pMesh ,pSol ); +int MMG_unscaleMesh(pMesh ,pSol ); + +int MMG_mmg3d1(pMesh ,pSol ,int *); +int MMG_mmg3d9(pMesh ,pSol ,int *); + + +/* zaldy */ +int MMG_newPt(pMesh ,double *c); +int MMG_newElt(pMesh ); +int MMG_getnElt(pMesh ,int ); +int MMG_newTria(pMesh ); +void MMG_delPt(pMesh ,int ); +void MMG_delElt(pMesh ,int ); +void MMG_delTria(pMesh ,int ); +int MMG_zaldy(pMesh ); +int MMG_zaldy3(pSol ); +int MMG_zaldy4(pHedge ,int ); + +int MMG_optra4(pMesh ,pSol ); +int MMG_optcoq(pMesh ,pSol); +int MMG_opttet(pMesh ,pSol); +int MMG_opttyp(pMesh ,pSol ,float ,int *); +int MMG_optbdry(pMesh ,pSol ,int ); +int MMG_opt2peau(pMesh ,pSol ,pQueue ,int ,float ); +int MMG_optlap(pMesh ,pSol ); + +/* swapar */ +typedef int (*MMG_Swap)(pMesh ,pSol ,pList ); +//MMG_Swap MMG_swpptr; + +int MMG_swapar(pMesh ,pSol ,pQueue ,List *,int ,float ,float ); + +int MMG_simu23(pMesh ,pSol ,int ,int ,float ); +int MMG_simu32(pMesh ,pSol ,pList ,float ); +int MMG_swap32(pMesh ,pSol ,pList ); +int MMG_swap23(pMesh ,pSol ,pQueue ,int ,int ,float ); + +int MMG_simu44(pMesh ,pSol ,pList ,float ); +int MMG_swap44_1(pMesh ,pSol ,pList ); +int MMG_swap44_2(pMesh ,pSol ,pList ); + +int MMG_simu56(pMesh ,pSol ,pList ,float ); +int MMG_swap56_1(pMesh ,pSol ,pList ); +int MMG_swap56_2(pMesh ,pSol ,pList ); +int MMG_swap56_3(pMesh ,pSol ,pList ); +int MMG_swap56_4(pMesh ,pSol ,pList ); +int MMG_swap56_5(pMesh ,pSol ,pList ); + +int MMG_simu68(pMesh ,pSol ,pList ,float ); +int MMG_swap68_1(pMesh ,pSol ,pList ); +int MMG_swap68_2(pMesh ,pSol ,pList ); +int MMG_swap68_3(pMesh ,pSol ,pList ); +int MMG_swap68_4(pMesh ,pSol ,pList ); +int MMG_swap68_5(pMesh ,pSol ,pList ); +int MMG_swap68_6(pMesh ,pSol ,pList ); +int MMG_swap68_7(pMesh ,pSol ,pList ); +int MMG_swap68_8(pMesh ,pSol ,pList ); +int MMG_swap68_9(pMesh ,pSol ,pList ); +int MMG_swap68_10(pMesh ,pSol ,pList ); +int MMG_swap68_11(pMesh ,pSol ,pList ); +int MMG_swap68_12(pMesh ,pSol ,pList ); +int MMG_swap68_13(pMesh ,pSol ,pList ); +int MMG_swap68_14(pMesh ,pSol ,pList ); + +int MMG_simu710(pMesh ,pSol ,pList ,float ); +int MMG_swap710_1(pMesh ,pSol ,pList ); +int MMG_swap710_2(pMesh ,pSol ,pList ); +int MMG_swap710_3(pMesh ,pSol ,pList ); +int MMG_swap710_4(pMesh ,pSol ,pList ); +int MMG_swap710_5(pMesh ,pSol ,pList ); +int MMG_swap710_6(pMesh ,pSol ,pList ); +int MMG_swap710_7(pMesh ,pSol ,pList ); +int MMG_swap710_8(pMesh ,pSol ,pList ); +int MMG_swap710_9(pMesh ,pSol ,pList ); +int MMG_swap710_10(pMesh ,pSol sol,pList list); +int MMG_swap710_11(pMesh ,pSol sol,pList list); +int MMG_swap710_12(pMesh ,pSol sol,pList list); +int MMG_swap710_13(pMesh ,pSol ,pList ); +int MMG_swap710_14(pMesh ,pSol ,pList ); +int MMG_swap710_15(pMesh ,pSol ,pList ); +int MMG_swap710_16(pMesh ,pSol ,pList ); +int MMG_swap710_17(pMesh ,pSol ,pList ); +int MMG_swap710_18(pMesh ,pSol ,pList ); +int MMG_swap710_19(pMesh ,pSol ,pList ); +int MMG_swap710_20(pMesh ,pSol ,pList ); +int MMG_swap710_21(pMesh ,pSol ,pList ); +int MMG_swap710_22(pMesh ,pSol ,pList ); +int MMG_swap710_23(pMesh ,pSol ,pList ); +int MMG_swap710_24(pMesh ,pSol ,pList ); +int MMG_swap710_25(pMesh ,pSol ,pList ); +int MMG_swap710_26(pMesh ,pSol ,pList ); +int MMG_swap710_27(pMesh ,pSol ,pList ); +int MMG_swap710_28(pMesh ,pSol ,pList ); +int MMG_swap710_29(pMesh ,pSol ,pList ); +int MMG_swap710_30(pMesh ,pSol ,pList ); +int MMG_swap710_31(pMesh ,pSol ,pList ); +int MMG_swap710_32(pMesh ,pSol ,pList ); +int MMG_swap710_33(pMesh ,pSol ,pList ); +int MMG_swap710_34(pMesh ,pSol ,pList ); +int MMG_swap710_35(pMesh ,pSol ,pList ); +int MMG_swap710_36(pMesh ,pSol ,pList ); +int MMG_swap710_37(pMesh ,pSol ,pList ); +int MMG_swap710_38(pMesh ,pSol ,pList ); +int MMG_swap710_39(pMesh ,pSol ,pList ); +int MMG_swap710_40(pMesh ,pSol ,pList ); +int MMG_swap710_41(pMesh ,pSol ,pList ); +int MMG_swap710_42(pMesh ,pSol ,pList ); + +int MMG_typelt(pMesh ,int ,int *); + +/* function pointers */ +extern double (*MMG_length)(pMesh ,pSol ,int ,int ); +extern double (*MMG_caltet)(pMesh ,pSol ,int ); +extern double (*MMG_calte1)(pMesh ,pSol ,int ); +extern int (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *); +extern int (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int ); +extern int (*MMG_buckin)(pMesh ,pSol ,pBucket ,int ); +extern int (*MMG_optlen)(pMesh ,pSol ,float ,int ); +extern int (*MMG_interp)(double *,double *,double *,float ); +extern int (*MMG_optlentet)(pMesh ,pSol ,pQueue ,float ,int ,int ); +extern int (*MMG_movevertex)(pMesh ,pSol ,int ,int ); + +/* quality */ +double MMG_voltet(pMesh ,int ); +double MMG_quickvol(double *,double *,double *,double *); +int MMG_prilen(pMesh ,pSol ); +void MMG_outqua(pMesh ,pSol ); +double MMG_priworst(pMesh , pSol ); + +int MMG_chkmsh(pMesh ,int ,int ); + +/* bucket */ +pBucket MMG_newBucket(pMesh ,int ); +int MMG_addBucket(pMesh ,pBucket ,int ); +int MMG_delBucket(pMesh ,pBucket ,int ); +void MMG_freeBucket(pBucket ); + +/* heap */ +Heap *MMG_hipini(pMesh ,int ,short ,float ,int ); +void MMG_hipfree(Heap *); +int MMG_hipput(pMesh ,Heap *,int ); +int MMG_hippop(pMesh ,Heap *); +void MMG_hiprep(pMesh ,Heap *,int ); +void MMG_hipdel(pMesh ,Heap *,int ); + +/* queue */ +pQueue MMG_kiuini(pMesh ,int ,float ,int ); +int MMG_kiupop(pQueue ); +int MMG_kiudel(pQueue ,int ); +int MMG_kiuput(pQueue ,int ); +void MMG_kiufree(pQueue ); + +/* matrices */ +int MMG_invmat(double *,double *); + +double MMG_calte3_ani(pMesh mesh,pSol sol,int iel); + diff --git a/contrib/mmg3d/build/sources/swap23.c b/contrib/mmg3d/build/sources/swap23.c new file mode 100644 index 0000000000..f51bfef104 --- /dev/null +++ b/contrib/mmg3d/build/sources/swap23.c @@ -0,0 +1,678 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_swap23(pMesh mesh,pSol sol,pQueue q, int iel,int iar, double declic) { + pTetra pt,pt_a,pt1,pt2,pt3; + int jel,*adja,*adja_a,i_a,v,v_a,voy_a,a0,a1,a2; + int iadr,kel,lel,*adja1,adj0,adj1,adj2; + int s[3],n0,n1,n2,ref; + + pt = &mesh->tetra[iel]; + ref = pt->ref; + iadr = 4*(iel-1) + 1; + adja = &mesh->adja[iadr]; + v = pt->v[iar]; + + i_a = adja[iar] >> 2; + assert(i_a); + voy_a = adja[iar] % 4; + pt_a = &mesh->tetra[i_a]; + v_a = pt_a->v[voy_a]; + iadr = 4*(i_a-1) + 1; + adja_a = &mesh->adja[iadr]; + + /*check iel and i_a in the same SD*/ + if(pt->ref != pt_a->ref) return(0); + + n0 = MMG_idir[iar][0]; + n1 = MMG_idir[iar][1]; + n2 = MMG_idir[iar][2]; + + s[0] = pt->v[n0]; + s[1] = pt->v[n1]; + s[2] = pt->v[n2]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[1] = v_a; + pt1->v[0] = v; + pt1->v[2] = s[0]; + pt1->v[3] = s[1]; + pt1->qual = MMG_caltet(mesh,sol,jel); + pt1->flag = mesh->flag; + pt1->ref = ref; + if ( pt1->qual >= declic ) MMG_kiuput(q,jel); + + kel = MMG_newElt(mesh); + pt2 = &mesh->tetra[kel]; + pt2->v[1] = v_a; + pt2->v[0] = v; + pt2->v[2] = s[1]; + pt2->v[3] = s[2]; + pt2->qual = MMG_caltet(mesh,sol,kel); + pt2->flag = mesh->flag; + pt2->ref = ref; + if ( pt2->qual >= declic ) MMG_kiuput(q,kel); + + lel = MMG_newElt(mesh); + pt3 = &mesh->tetra[lel]; + pt3->v[1] = v_a; + pt3->v[0] = v; + pt3->v[2] = s[2]; + pt3->v[3] = s[0]; + pt3->qual = MMG_caltet(mesh,sol,lel); + pt3->flag = mesh->flag; + pt3->ref = ref; + if ( pt3->qual >= declic ) MMG_kiuput(q,lel); + +//printf("qual %e %e %e\n",pt1->qual,pt2->qual,pt3->qual); + /*neighboors*/ + a0 = n0; + a1 = n1; + a2 = n2; + + if(pt->v[MMG_idir[n0][0]] == v) { + if(pt->v[MMG_idir[n0][1]] == s[0] + || pt->v[MMG_idir[n0][2]] == s[0]) { + if(pt->v[MMG_idir[n0][1]] == s[1] + || pt->v[MMG_idir[n0][2]] == s[1]) + a0 = n0; + else { + assert(pt->v[MMG_idir[n0][1]] == s[2] + || pt->v[MMG_idir[n0][2]] == s[2]); + a2 = n0; + } + } else { + a1 = n0; + } + } else if(pt->v[MMG_idir[n0][1]] == v){ + if(pt->v[MMG_idir[n0][0]] == s[0] + || pt->v[MMG_idir[n0][2]] == s[0]) { + if(pt->v[MMG_idir[n0][0]] == s[1] + || pt->v[MMG_idir[n0][2]] == s[1]) + a0 = n0; + else { + assert(pt->v[MMG_idir[MMG_idir[iar][0]][0]] == s[2] + || pt->v[MMG_idir[MMG_idir[iar][0]][2]] == s[2]); + a2 = n0; + } + } else { + a1 = n0; + } + } else { + assert(pt->v[MMG_idir[n0][2]] == v); + if(pt->v[MMG_idir[n0][1]] == s[0] + || pt->v[MMG_idir[n0][0]] == s[0]) { + if(pt->v[MMG_idir[n0][1]] == s[1] + || pt->v[MMG_idir[n0][0]] == s[1]) + a0 = n0; + else { + assert(pt->v[MMG_idir[n0][1]] == s[2] + || pt->v[MMG_idir[n0][0]] == s[2]); + a2 = n0; + } + } else { + a1 = n0; + } + } + + if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == v) { + if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[0] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[0]) { + if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[1] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[1]) + a0 = MMG_idir[iar][1]; + else { + assert(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[2] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[2]); + a2 = MMG_idir[iar][1]; + } + } else { + a1 = MMG_idir[iar][1]; + } + } else if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == v){ + if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[0] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[0]) { + if(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[1] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[1]) + a0 = MMG_idir[iar][1]; + else { + assert(pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[2] + || pt->v[MMG_idir[MMG_idir[iar][1]][2]] == s[2]); + a2 = MMG_idir[iar][1]; + } + } else { + a1 = MMG_idir[iar][1]; + } + } else { + assert(pt->v[MMG_idir[MMG_idir[iar][1]][2]] == v); + if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[0] + || pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[0]) { + if(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[1] + || pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[1]) + a0 = MMG_idir[iar][1]; + else { + assert(pt->v[MMG_idir[MMG_idir[iar][1]][1]] == s[2] + || pt->v[MMG_idir[MMG_idir[iar][1]][0]] == s[2]); + a2 = MMG_idir[iar][1]; + } + } else { + a1 = MMG_idir[iar][1]; + } + } + + if(pt->v[MMG_idir[n2][0]] == v) { + if(pt->v[MMG_idir[n2][1]] == s[0] + || pt->v[MMG_idir[n2][2]] == s[0]) { + if(pt->v[MMG_idir[n2][1]] == s[1] + || pt->v[MMG_idir[n2][2]] == s[1]) + a0 = n2; + else { + assert(pt->v[MMG_idir[n2][1]] == s[2] + || pt->v[MMG_idir[n2][2]] == s[2]); + a2 = n2; + } + } else { + a1 = n2; + } + } else if(pt->v[MMG_idir[n2][1]] == v){ + if(pt->v[MMG_idir[n2][0]] == s[0] + || pt->v[MMG_idir[n2][2]] == s[0]) { + if(pt->v[MMG_idir[n2][0]] == s[1] + || pt->v[MMG_idir[n2][2]] == s[1]) + a0 = n2; + else { + assert(pt->v[MMG_idir[n2][0]] == s[2] + || pt->v[MMG_idir[n2][2]] == s[2]); + a2 = n2; + } + } else { + a1 = n2; + } + } else { + assert(pt->v[MMG_idir[n2][2]] == v); + if(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[0] + || pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[0]) { + if(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[1] + || pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[1]) + a0 = MMG_idir[iar][2]; + else { + assert(pt->v[MMG_idir[MMG_idir[iar][2]][1]] == s[2] + || pt->v[MMG_idir[MMG_idir[iar][2]][0]] == s[2]); + a2 = MMG_idir[iar][2]; + } + } else { + a1 = MMG_idir[iar][2]; + } + } + + adj0 = MMG_idir[voy_a][0]; + adj1 = MMG_idir[voy_a][1]; + adj2 = MMG_idir[voy_a][2]; + + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == v_a) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[1]) + adj0 = MMG_idir[voy_a][0]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[2]); + adj2 = MMG_idir[voy_a][0]; + } + } else { + adj1 = MMG_idir[voy_a][0]; + } + } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == v_a){ + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[1]) + adj0 = MMG_idir[voy_a][0]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == s[2]); + adj2 = MMG_idir[voy_a][0]; + } + } else { + adj1 = MMG_idir[voy_a][0]; + } + } else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][2]] == v_a); + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[1]) + adj0 = MMG_idir[voy_a][0]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][0]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][0]][0]] == s[2]); + adj2 = MMG_idir[voy_a][0]; + } + } else { + adj1 = MMG_idir[voy_a][0]; + } + } + + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == v_a) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[1]) + adj0 = MMG_idir[voy_a][1]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[2]); + adj2 = MMG_idir[voy_a][1]; + } + } else { + adj1 = MMG_idir[voy_a][1]; + } + } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == v_a){ + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[1]) + adj0 = MMG_idir[voy_a][1]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == s[2]); + adj2 = MMG_idir[voy_a][1]; + } + } else { + adj1 = MMG_idir[voy_a][1]; + } + } else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][2]] == v_a); + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[1]) + adj0 = MMG_idir[voy_a][1]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][1]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][1]][0]] == s[2]); + adj2 = MMG_idir[voy_a][1]; + } + } else { + adj1 = MMG_idir[voy_a][1]; + } + } + + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == v_a) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[1]) + adj0 = MMG_idir[voy_a][2]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[2]); + adj2 = MMG_idir[voy_a][2]; + } + } else { + adj1 = MMG_idir[voy_a][2]; + } + } else if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == v_a){ + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[1]) + adj0 = MMG_idir[voy_a][2]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == s[2]); + adj2 = MMG_idir[voy_a][2]; + } + } else { + adj1 = MMG_idir[voy_a][2]; + } + } else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][2]] == v_a); + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[0] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[0]) { + if(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[1] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[1]) + adj0 = MMG_idir[voy_a][2]; + else { + assert(pt_a->v[MMG_idir[MMG_idir[voy_a][2]][1]] == s[2] + || pt_a->v[MMG_idir[MMG_idir[voy_a][2]][0]] == s[2]); + adj2 = MMG_idir[voy_a][2]; + } + } else { + adj1 = MMG_idir[voy_a][2]; + } + } + + iadr = 4*(jel-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[1] = adja[a0]; + adja1[0] = adja_a[adj0]; + adja1[2] = 4*kel + 3; + adja1[3] = 4*lel + 2; + pt1->bdryref[0] = pt_a->bdryref[adj0]; + pt1->bdryref[1] = pt->bdryref[a0]; + pt1->bdryref[2] = -1; + pt1->bdryref[3] = -1; + + + + if ((adja[a0]>>2)) { + iadr = 4*((adja[a0]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja[a0]%4] = 4*jel + 1; + } + + if (adja_a[adj0]>>2) { + iadr = 4*((adja_a[adj0]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja_a[adj0]%4] = 4*jel ; + } + + iadr = 4*(kel-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[1] = adja[a1]; + adja1[0] = adja_a[adj1]; + adja1[2] = 4*lel + 3; + adja1[3] = 4*jel + 2; + pt2->bdryref[0] = pt_a->bdryref[adj1]; + pt2->bdryref[1] = pt->bdryref[a1]; + pt2->bdryref[2] = -1; + pt2->bdryref[3] = -1; + + if ((adja[a1]>>2)) { + iadr = 4*((adja[a1]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja[a1]%4] = 4*kel + 1; + } + + if ((adja_a[adj1]>>2)) { + iadr = 4*((adja_a[adj1]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja_a[adj1]%4] = 4*kel ; + } + + iadr = 4*(lel-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[1] = adja[a2]; + adja1[0] = adja_a[adj2]; + adja1[2] = 4*jel + 3; + adja1[3] = 4*kel + 2; + pt3->bdryref[0] = pt_a->bdryref[adj2]; + pt3->bdryref[1] = pt->bdryref[a2]; + pt3->bdryref[2] = -1; + pt3->bdryref[3] = -1; + + if ((adja[a2]>>2)) { + iadr = 4*((adja[a2]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja[a2]%4] = 4*lel + 1; + } + + if ((adja_a[adj2]>>2)) { + iadr = 4*((adja_a[adj2]>>2)-1) + 1; + adja1 = &mesh->adja[iadr]; + adja1[adja_a[adj2]%4] = 4*lel; + } + + /*del*/ + MMG_delElt(mesh,iel); + MMG_delElt(mesh,i_a); + MMG_kiudel(q,iel); + MMG_kiudel(q,i_a); + + + return(1); +} + + +/* remove edge AB */ +int MMG_swap32(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt2,pt0; + Hedge hed; + int *adja,k,i,jel,kel,adj,iadr,ia,ib,s1,s2,s3; + int old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,10) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP32 IGNORED\n"); + } + + /* face s1 s2 s3 */ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + //printf("1. insere %d %d -- %d\n",pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] >> 2; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + /* create 2 new tetra */ + /*edge : ias1 -- ias2 -- ias3 -- s1s2 -- s1s3 -- s2s3*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* 2nd elt */ + /*edge : ibs2 -- ibs1 -- ibs3 -- s2s1 -- s2s3 -- s2s3*/ + kel = MMG_newElt(mesh); + pt2 = &mesh->tetra[kel]; + pt2->v[0] = ib; + pt2->v[1] = s2; + pt2->v[2] = s1; + pt2->v[3] = s3; + pt2->qual = list->qual[2]; + pt2->flag = mesh->flag; + pt2->ref = ref; + + /* external faces */ + for (k=2; k<=3; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + //printf("2. insere %d %d -- %d\n",pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if( pt0->v[kk] == ib ) { + adj_a = adja[kk] >> 2; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] >> 2; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } + else /*if ( pt0->v[MMG_iare[iarold][0]] == ib ) */{ + adj_b = adja[kk] >> 2; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] >> 2; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if ( old == (adja[MMG_isar[iar][0]]>>2) ) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + pt1->bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + pt2->bdryref[2] = ref_b; + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 2; + } + } + else if ( old == (adja[MMG_isar[iar][1]]>>2) ) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + pt1->bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + pt2->bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } + + } + + /* du tetra 1 de la liste pour ia */ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] >> 2; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + pt1->bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + /* du tetra 1 de la liste pour ib */ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] >> 2; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + pt2->bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + + /* internal face */ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + //printf("pas trouve %d %d\n",pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]]); + assert(pt1->bdryinfo[i]!=1); + pt2->bdryinfo[i] = MMG_edgePut(&hed,pt2->v[MMG_iare[i][0]],pt2->v[MMG_iare[i][1]],1); + assert(pt2->bdryinfo[i]!=1); + } + + /* remove 3 old tetra */ + for (k=1; k<=3; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = 0; + + M_free(hed.item); + return(2); +} + diff --git a/contrib/mmg3d/build/sources/swap44.c b/contrib/mmg3d/build/sources/swap44.c new file mode 100644 index 0000000000..b8d645576d --- /dev/null +++ b/contrib/mmg3d/build/sources/swap44.c @@ -0,0 +1,608 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* remove edge iar of iel */ +int MMG_swap44_1(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt0,pt1; + Hedge hed; + int *adja,i,k,jel,kel,lel,mel,adj,base,iadr,ia,ib,s1,s2,s3,s4; + int old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,13) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP441 IGNORED\n"); + } + + /* face s1 s2 s3 */ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + base = mesh->mark; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + /* create 4 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* 2nd elt */ + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* 2nd elt */ + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + if(iadr<0) {puts("aaaaaaaaaaaa");exit(0);} + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=4 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 2; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 3; + } + } else { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + + } + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + + /* internal face */ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + + /* remove 4 old tetra */ + for (k=1; k<=4; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = 0; + + M_free(hed.item); + return(4); +} + + +/* remove edge iar of iel */ +int MMG_swap44_2(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt0,pt1; + Hedge hed; + int *adja,i,k,jel,kel,lel,mel,adj,base,iadr,ia,ib,s1,s2,s3,s4; + int old,iarold,kk,adj_a,adj_b,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,13) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + /* face s1 s2 s3 */ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + base = mesh->mark; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + //printf("on insere %d %d -- %d\n",pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + /* create 4 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* 2nd elt */ + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* 2nd elt */ + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /* external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=4 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + //printf("2. on insere %d %d -- %d\n",pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b){ + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + + } + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + + /* internal face */ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + + /* remove 4 old tetra */ + for (k=1; k<=4; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = 0; + + M_free(hed.item); + + return(4); +} diff --git a/contrib/mmg3d/build/sources/swap56.c b/contrib/mmg3d/build/sources/swap56.c new file mode 100644 index 0000000000..a116080e05 --- /dev/null +++ b/contrib/mmg3d/build/sources/swap56.c @@ -0,0 +1,1956 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_swap56_1(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s1,s2,s3,s4,s5; + int jel,kel,lel,mel,nel,pel; + int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,17) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + /* create 6 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s4; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s4; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=5 ; k++) { + + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b){ + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 2; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s2) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==adja[j] / 4) { + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a){ + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 1; + } + } + } + + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = pel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = lel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[nel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[pel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + + + /* remove 5 old tetra */ + for (k=1; k<=5; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = pel; + list->tetra[7] = 0; + M_free(hed.item); + return(6); +} + + +int MMG_swap56_2(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s1,s2,s3,s4,s5; + int jel,kel,lel,mel,nel,pel; + int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,17) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + /* create 6 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s5; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ib; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s4; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=5 ; k++) { + + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s2) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==adja[j] / 4) { + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 1; + } + } + } + + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = nel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = pel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 3; + + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = pel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = jel*4 + 1; + adja[3] = lel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = kel*4 + 1; + adja[2] = mel*4 + 3; + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[nel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[pel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + /* remove 5 old tetra */ + for (k=1; k<=5; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = pel; + list->tetra[7] = 0; + M_free(hed.item); + + return(6); +} + + +int MMG_swap56_3(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s1,s2,s3,s4,s5; + int jel,kel,lel,mel,nel,pel; + int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,17) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + /* create 6 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s3; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s3; + pt1->v[3] = s5; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ib; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s4; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=5 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a){ + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 2; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 3; + } + } else { + + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s2) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==adja[j] / 4) { + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 2; + } + } else { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 1; + } + } + } + + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[1] = pel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[nel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[pel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + + /* remove 5 old tetra */ + for (k=1; k<=5; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = pel; + list->tetra[7] = 0; + M_free(hed.item); + + return(6); +} + + +int MMG_swap56_4(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s1,s2,s3,s4,s5; + int jel,kel,lel,mel,nel,pel; + int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + if ( !MMG_zaldy4(&hed,17) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + /* create 6 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s5; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s4; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s4; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s2; + pt1->v[2] = s4; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s4; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s4; + pt1->v[3] = s2; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + + for(k=2 ; k<=5 ; k++) { + + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s2) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==adja[j] / 4) { + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } + } + + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = nel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = pel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = jel*4 + 3; + adja[1] = lel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = kel*4 + 2; + adja[1] = mel*4 + 3; + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[nel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[pel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + /* remove 5 old tetra */ + for (k=1; k<=5; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = pel; + list->tetra[7] = 0; + + M_free(hed.item); + + return(6); +} + + +int MMG_swap56_5(pMesh mesh,pSol sol,pList list) { + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s1,s2,s3,s4,s5; + int jel,kel,lel,mel,nel,pel; + int iadr,iarold,*adja,k,adj,old,kk,adj_a,adj_b,j,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + if ( !MMG_zaldy4(&hed,17) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP442 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s3 = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("point non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + /* create 6 new tetra */ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s1; + pt1->v[2] = s2; + pt1->v[3] = s5; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s1; + pt1->v[2] = s5; + pt1->v[3] = s2; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s2; + pt1->v[2] = s3; + pt1->v[3] = s5; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s2; + pt1->v[2] = s5; + pt1->v[3] = s3; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s3; + pt1->v[2] = s4; + pt1->v[3] = s5; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ib; + pt1->v[1] = s3; + pt1->v[2] = s5; + pt1->v[3] = s4; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=5 ; k++) { + + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s2) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 2; + } + } else { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[pel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = pel*4 + 1; + } + } + } + + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = jel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = pel*4 + 3; + adja[3] = kel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + + /*bdryinfo*/ + pt1 = &mesh->tetra[jel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[kel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[lel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[mel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[nel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + pt1 = &mesh->tetra[pel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(&hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + /* remove 5 old tetra */ + for (k=1; k<=5; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = pel; + list->tetra[7] = 0; + M_free(hed.item); + + return(6); +} diff --git a/contrib/mmg3d/build/sources/swap68.c b/contrib/mmg3d/build/sources/swap68.c new file mode 100644 index 0000000000..ec7c45dc7e --- /dev/null +++ b/contrib/mmg3d/build/sources/swap68.c @@ -0,0 +1,5674 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/*find points of polygone*/ +static int MMG_findpolygone(pMesh mesh,int iel,int iar,int *s) { + pTetra pt,pt1; + int ia,ib; + int iadr,*adja,k,adj; + int s1,s2,s3,s4,s5,s6; + short voy; + + pt = &mesh->tetra[iel]; + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + s1 = pt->v[ MMG_isar[iar][0] ]; + s2 = pt->v[ MMG_isar[iar][1] ]; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + + s3 = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s2) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s2) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s2) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu56_ani: point s2 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s4 = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_idir[voy][0]]==s3) { + k = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s3) { + k = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s3) { + k = MMG_idir[voy][2]; + } else { + puts("MMG_simu56_ani: point s4 non existant"); + exit(0); + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s5 = pt1->v[voy]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + s6 = pt1->v[voy]; + + /*printf("polygone : %d %d %d %d %d %d\n",s1,s2,s3,s4,s5,s6);*/ + s[0]=s1; + s[1]=s2; + s[2]=s3; + s[3]=s4; + s[4]=s5; + s[5]=s6; + return(1); +} + +static int MMG_updatebdryinfo(pMesh mesh,pHedge hed,pList list) { + pTetra pt1; + int iel,i,k; + + for(k=1 ; k<=8 ; k++) { + iel = list->tetra[k]; + pt1 = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + } + + return(1); +} + +int MMG_swap68_1(pMesh mesh,pSol sol,pList list) { + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP661 IGNORED\n"); + } + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + //printf("nx : %d %d %d %d %d %d %d %d\n",jel,kel,lel,mel,nel,oel,pel,qel); + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 2; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old == adja[j] / 4) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + + /* remove 6 old tetra */ + for (k=1; k<=6; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_2(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP662 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 2; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_3(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 2; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 2; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_4(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP684 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 2; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_5(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP685 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 3; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 2; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a){ + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_6(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP686 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 3; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 2; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_7(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP687 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 3; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 2; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_8(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP688 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_9(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP689 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 2; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = qel*4 + 3; + + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = nel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = oel*4 + 2; + adja[2] = kel*4 + 3; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_10(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6810 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 3; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 2; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_11(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6811 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 3; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 2; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 1; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_12(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6812 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a){ + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 3; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 2; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_13(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6813 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 3; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 2; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[pel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = pel*4 + 1; + } + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[qel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = qel*4 + 1; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 2; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} + +int MMG_swap68_14(pMesh mesh,pSol sol,pList list){ + pTetra pt1,pt,pt0; + Hedge hed; + int i,ia,ib,s[6],j; + int jel,kel,lel,mel,nel,oel,pel,qel; + int iarold,iadr,*adja,k,adj,adj_a,adj_b,old,kk,iel,iar,ref,ref_a,ref_b; + short voy,voy_a,voy_b; + + if ( !MMG_zaldy4(&hed,21) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP6814 IGNORED\n"); + } + + + /*find points of polygone*/ + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + if(!MMG_findpolygone(mesh,iel,iar,s)) return(0); + + pt = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt->v[MMG_iare[i][0]],pt->v[MMG_iare[i][1]],pt->bdryinfo[i]); + } + ref = pt->ref; + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + /*create 8 tetras*/ + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->flag = mesh->flag; + pt1->ref = ref; + + /*external faces*/ + /*tetra iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_iare[iar][0]; + adj = adja[k] / 4; + voy = adja[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + for(k=2 ; k<=6 ; k++) { + old = list->tetra[k] / 6; + iadr = (old-1)*4 + 1; + adja = &mesh->adja[iadr]; + + pt0 = &mesh->tetra[old]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + iarold = list->tetra[k] % 6; + kk = MMG_iare[iarold][1]; + if(pt0->v[kk]==ib) { + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + } else /*if(pt0->v[MMG_iare[iarold][0]]==ib)*/{ + adj_b = adja[kk] / 4; + voy_b = adja[kk] % 4; + ref_b = pt0->bdryref[kk]; + kk = MMG_iare[iarold][0]; + adj_a = adja[kk] / 4; + voy_a = adja[kk] % 4; + ref_a = pt0->bdryref[kk]; + } + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[1] appartient a old */ + if(old==(adja[MMG_isar[iar][0]]/4)) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 3; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 2; + } + + } else if(old==(adja[MMG_isar[iar][1]]/4)){ + /*s[0] appartient a old*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_a*4 + voy_a; + mesh->tetra[jel].bdryref[2] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = jel*4 + 2; + } + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_b*4 + voy_b; + mesh->tetra[kel].bdryref[3] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = kel*4 + 3; + } + } else { + /*old n'est pas un voisin de iel*/ + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][0]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[1]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[1]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[1]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[2] s[3] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[lel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = lel*4 + 1; + } + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[mel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = mel*4 + 1; + } + } else { + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + j = MMG_isar[iar][1]; + adj = adja[j] / 4; + voy = adja[j] % 4; + pt1 = &mesh->tetra[adj]; + + if(pt1->v[MMG_idir[voy][0]]==s[0]) { + j = MMG_idir[voy][0]; + } else if(pt1->v[MMG_idir[voy][1]]==s[0]) { + j = MMG_idir[voy][1]; + } else if(pt1->v[MMG_idir[voy][2]]==s[0]) { + j = MMG_idir[voy][2]; + } + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + /*s[4] s[5] appartient a old*/ + if(old == adja[j] / 4) { + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[1] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 1; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[1] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 1; + } + } + else { + /*s[3] s[4] appartient a old*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj_a*4 + voy_a; + mesh->tetra[nel].bdryref[3] = ref_a; + + if (adj_a) { + iadr = (adj_a-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_a] = nel*4 + 3; + } + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj_b*4 + voy_b; + mesh->tetra[oel].bdryref[2] = ref_b; + + if (adj_b) { + iadr = (adj_b-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy_b] = oel*4 + 2; + } + } + } + } + } + + /*internal faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = pel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = qel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = jel*4 + 1; + adja[3] = lel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = kel*4 + 1; + adja[2] = mel*4 + 3; + /* remove 6 old tetra */ + for (k=1; k<=6; k++) + MMG_delElt(mesh,list->tetra[k]/6); + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(8); +} diff --git a/contrib/mmg3d/build/sources/swap710.c b/contrib/mmg3d/build/sources/swap710.c new file mode 100644 index 0000000000..b58b84adf2 --- /dev/null +++ b/contrib/mmg3d/build/sources/swap710.c @@ -0,0 +1,19044 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/*find points of polygone*/ +static int MMG_findpolygone(pMesh mesh,pList list,int *s) { + pTetra pt,pt1; + int ia,ib; + int j,iadr,*adja,k,adj,iar,iel; + short voy; + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + + /*find points of polygone*/ + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; +// printf("MMG_swap edge %d %d\n",ia,ib); + s[0] = pt->v[ MMG_isar[iar][0] ]; + s[1] = pt->v[ MMG_isar[iar][1] ]; + + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][0]; + + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + iar = j; + list->tetra[2] = 6*adj + iar; + + s[2] = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_isar[iar][0]] == s[1]) { + k = MMG_isar[iar][0]; + } else { + assert(pt1->v[MMG_isar[iar][1]] == s[1]); + k = MMG_isar[iar][1]; + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + iar = j; + list->tetra[3] = 6*adj + iar; + + s[3] = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_isar[iar][0]] == s[2]) { + k = MMG_isar[iar][0]; + } else { + assert(pt1->v[MMG_isar[iar][1]] == s[2]); + k = MMG_isar[iar][1]; + } + + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + iar = j; + list->tetra[4] = 6*adj + iar; + + s[4] = pt1->v[voy]; + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_isar[iar][0]] == s[3]) { + k = MMG_isar[iar][0]; + } else { + assert(pt1->v[MMG_isar[iar][1]] == s[3]); + k = MMG_isar[iar][1]; + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + iar = j; + list->tetra[5] = 6*adj + iar; + + s[5] = pt1->v[voy]; + + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + if(pt1->v[MMG_isar[iar][0]] == s[4]) { + k = MMG_isar[iar][0]; + } else { + assert(pt1->v[MMG_isar[iar][1]] == s[4]); + k = MMG_isar[iar][1]; + } + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + iar = j; + list->tetra[6] = 6*adj + j; + + iar = list->tetra[1] % 6; + iadr = (iel-1)*4 + 1; + adja = &mesh->adja[iadr]; + k = MMG_isar[iar][1]; + adj = adja[k] / 4; + voy = adja[k] % 4; + pt1 = &mesh->tetra[adj]; + for(j=0 ; j<6 ; j++) + if((ia == pt1->v[MMG_iare[j][0]] && ib ==pt1->v[MMG_iare[j][1]]) || + (ia == pt1->v[MMG_iare[j][1]] && ib ==pt1->v[MMG_iare[j][0]])) break; + assert(j<6); + list->tetra[7] = 6*adj + j; + + s[6] = pt1->v[voy]; + + return(1); +} + +static int MMG_updatebdryinfo(pMesh mesh,pHedge hed,pList list) { + pTetra pt1; + int iel,i,k; + + for(k=1 ; k<=10 ; k++) { + iel = list->tetra[k]; + pt1 = &mesh->tetra[iel]; + for(i=0 ; i<6 ; i++) { + pt1->bdryinfo[i] = MMG_edgePut(hed,pt1->v[MMG_iare[i][0]],pt1->v[MMG_iare[i][1]],1); + if(pt1->bdryinfo[i]<2) pt1->bdryinfo[i]=0; + } + } + + return(1); +} + +int MMG_swap710_1(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[3] = pel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[2] = qel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_2(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + adja[1] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + adja[1] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_3(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[3] = lel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[2] = mel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_4(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = pel*4 + 2; + adja[3] = lel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = qel*4 + 3; + adja[2] = mel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + adja[3] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + adja[2] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_5(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 2; + adja[2] = mel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_6(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 2; + adja[2] = kel*4 + 3; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_7(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_8(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = oel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = lel*4 + 2; + adja[3] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = mel*4 + 3; + adja[2] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_9(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = jel*4 + 3; + adja[1] = pel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = kel*4 + 2; + adja[1] = qel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + +/*printf("new tets %d %d %d %d %d %d %d %d %d %d\n",jel,kel,lel,mel,nel,oel,pel,qel,rel,sel); + */list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_10(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[3]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = nel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = oel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = jel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = kel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_11(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 2; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_12(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_13(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[2] = lel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[3] = mel*4 + 2; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); + +} +int MMG_swap710_14(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[2] = nel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[3] = oel*4 + 2; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = pel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = qel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_15(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + adja[3] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + adja[2] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = pel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = qel*4 + 2; + adja[2] = mel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_16(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 2; + adja[2] = mel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_17(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = qel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = lel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = mel*4 + 2; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_18(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 1; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 1; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = nel*4 + 1; + adja[3] = lel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = oel*4 + 1; + adja[2] = mel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_19(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 1; + adja[1] = pel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 1; + adja[1] = qel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = nel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = oel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} + +int MMG_swap710_20(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_21(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt = &mesh->tetra[iel]; + assert( pt->v[k] == ib); + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[rel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[sel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + adja[2] = mel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_22(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[3] = jel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[2] = kel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_23(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[3] = jel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[2] = kel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = pel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = qel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_24(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[3] = jel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[2] = kel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = pel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = qel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_25(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[3] = jel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[2] = kel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_26(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt = &mesh->tetra[iel]; + assert( pt->v[k] == ib); + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + adja[2] = mel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 1; + + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_27(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[rel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[sel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = nel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = oel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = pel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = qel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + adja[2] = lel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + adja[3] = mel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_28(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 1; + adja[3] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 1; + adja[2] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_29(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = pel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = qel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = nel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = oel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_30(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = lel*4 + 1; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = mel*4 + 1; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_31(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = lel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = mel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_32(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[pel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[qel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = lel*4 + 2; + adja[2] = pel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = mel*4 + 3; + adja[3] = qel*4 + 1; + adja[2] = oel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_33(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = nel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = oel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[3] = lel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[2] = mel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = lel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = mel*4 + 2; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_34(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_35(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + int ia,ib,s[7]; + Hedge hed; + int i,iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = lel*4 + 3; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = mel*4 + 2; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = jel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = kel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_36(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = nel*4 + 2; + adja[3] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = oel*4 + 3; + adja[2] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = lel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = mel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = lel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = mel*4 + 2; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_37(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if (adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_38(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[4]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[rel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = rel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[sel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = sel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[jel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[kel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[1] = lel*4 + 2; + adja[3] = rel*4 + 2; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[1] = mel*4 + 3; + adja[2] = sel*4 + 3; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = jel*4 + 1; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = kel*4 + 1; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 1; + adja[3] = nel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 1; + adja[2] = oel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = jel*4 + 3; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = kel*4 + 2; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_39(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = rel*4 + 3; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = sel*4 + 2; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = lel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = mel*4 + 1; + adja[2] = qel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} +int MMG_swap710_40(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[4]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[4]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[2]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[1]; + pt1->v[2] = s[4]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[1]; + pt1->v[2] = s[6]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[lel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[mel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 2; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[nel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[oel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 1; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 1; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[1] = rel*4 + 2; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[1] = sel*4 + 3; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[2] = rel*4 + 3; + adja[3] = lel*4 + 2; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[3] = sel*4 + 2; + adja[2] = mel*4 + 3; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = jel*4 + 2; + adja[2] = nel*4 + 1; + adja[3] = pel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = kel*4 + 3; + adja[3] = oel*4 + 1; + adja[2] = qel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; +//MMG_chkmsh(mesh,1,0); + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + return(1); +} +int MMG_swap710_41(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[3]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[3]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[pel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[qel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 1; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 1; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[1] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[1] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = lel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = mel*4 + 2; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + + return(1); +} +int MMG_swap710_42(pMesh mesh,pSol sol,pList list){ + pTetra pt,pt1,pt0; + Hedge hed; + int i,ia,ib,s[7]; + int iadr,iadr2,*adja,*adja2,k,k1,adj,iel,iar; + int jel,kel,lel,mel,nel,oel,pel,qel,rel,sel,ref; + short voy; + + if ( !MMG_zaldy4(&hed,25) ) { + if ( mesh->info.ddebug ) fprintf(stdout," ## MEMORY ALLOCATION PROBLEM : EDGES UPDATE SWAP663 IGNORED\n"); + } + + iel = list->tetra[1] / 6; + iar = list->tetra[1] % 6; + pt = &mesh->tetra[iel]; + ref = pt->ref; + MMG_findpolygone(mesh,list,s); + + ia = pt->v[ MMG_iare[iar][0] ]; + ib = pt->v[ MMG_iare[iar][1] ]; + + jel = MMG_newElt(mesh); + pt1 = &mesh->tetra[jel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[1]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[1]; + pt1->ref = ref; + + kel = MMG_newElt(mesh); + pt1 = &mesh->tetra[kel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[1]; + pt1->qual = list->qual[2]; + pt1->ref = ref; + + lel = MMG_newElt(mesh); + pt1 = &mesh->tetra[lel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[6]; + pt1->qual = list->qual[3]; + pt1->ref = ref; + + mel = MMG_newElt(mesh); + pt1 = &mesh->tetra[mel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[6]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[4]; + pt1->ref = ref; + + nel = MMG_newElt(mesh); + pt1 = &mesh->tetra[nel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[3]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[5]; + pt1->ref = ref; + + oel = MMG_newElt(mesh); + pt1 = &mesh->tetra[oel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[3]; + pt1->qual = list->qual[6]; + pt1->ref = ref; + + pel = MMG_newElt(mesh); + pt1 = &mesh->tetra[pel]; + pt1->v[0] = ia; + pt1->v[1] = s[2]; + pt1->v[2] = s[4]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[7]; + pt1->ref = ref; + + qel = MMG_newElt(mesh); + pt1 = &mesh->tetra[qel]; + pt1->v[0] = ib; + pt1->v[1] = s[2]; + pt1->v[2] = s[5]; + pt1->v[3] = s[4]; + pt1->qual = list->qual[8]; + pt1->ref = ref; + + rel = MMG_newElt(mesh); + pt1 = &mesh->tetra[rel]; + pt1->v[0] = ia; + pt1->v[1] = s[0]; + pt1->v[2] = s[2]; + pt1->v[3] = s[5]; + pt1->qual = list->qual[9]; + pt1->ref = ref; + + sel = MMG_newElt(mesh); + pt1 = &mesh->tetra[sel]; + pt1->v[0] = ib; + pt1->v[1] = s[0]; + pt1->v[2] = s[5]; + pt1->v[3] = s[2]; + pt1->qual = list->qual[10]; + pt1->ref = ref; + + /*adj of iel*/ + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[jel].bdryref[3] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 3; + } + k = MMG_iare[iar][0]; + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[kel].bdryref[2] = pt->bdryref[k]; + + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 2; + } + /*adj list->tetra[2]*/ + iel = list->tetra[2] / 6; + iar = list->tetra[2] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[jel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = jel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[kel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = kel*4 + 1; + } + /*adj list->tetra[3]*/ + iel = list->tetra[3] / 6; + iar = list->tetra[3] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[nel].bdryref[3] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 3; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + pt1 = &mesh->tetra[adj]; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[oel].bdryref[2] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 2; + } + /*adj list->tetra[4]*/ + iel = list->tetra[4] / 6; + iar = list->tetra[4] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[nel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = nel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[oel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = oel*4 + 1; + } + /*adj list->tetra[5]*/ + iel = list->tetra[5] / 6; + iar = list->tetra[5] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[pel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = pel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[qel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = qel*4 + 1; + } + /*adj list->tetra[6]*/ + iel = list->tetra[6] / 6; + pt = &mesh->tetra[iel]; + iar = list->tetra[6] % 6; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[lel].bdryref[1] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 1; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[1] = adj*4 + voy; + mesh->tetra[mel].bdryref[1] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 1; + } + /*adj list->tetra[7]*/ + iel = list->tetra[7] / 6; + iar = list->tetra[7] % 6; + pt = &mesh->tetra[iel]; + iadr2 = (iel-1)*4 + 1; + adja2 = &mesh->adja[iadr2]; + k = MMG_iare[iar][1]; + if(pt->v[k] == ib) + k1 = MMG_iare[iar][0]; + else { + k = MMG_iare[iar][0]; + k1 = MMG_iare[iar][1]; + } + adj = adja2[k] / 4; + voy = adja2[k] % 4; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[2] = adj*4 + voy; + mesh->tetra[lel].bdryref[2] = pt->bdryref[k]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = lel*4 + 2; + } + adj = adja2[k1] / 4; + voy = adja2[k1] % 4; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[3] = adj*4 + voy; + mesh->tetra[mel].bdryref[3] = pt->bdryref[k1]; + if(adj) { + iadr = (adj-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[voy] = mel*4 + 3; + } + /*internals faces*/ + iadr = (jel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = kel*4 + 0; + adja[2] = rel*4 + 3; + + iadr = (kel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = jel*4 + 0; + adja[3] = sel*4 + 2; + + iadr = (lel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = mel*4 + 0; + adja[3] = rel*4 + 2; + + iadr = (mel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = lel*4 + 0; + adja[2] = sel*4 + 3; + + iadr = (nel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = oel*4 + 0; + adja[2] = pel*4 + 3; + + iadr = (oel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = nel*4 + 0; + adja[3] = qel*4 + 2; + + iadr = (pel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = qel*4 + 0; + adja[3] = nel*4 + 2; + adja[2] = rel*4 + 1; + + iadr = (qel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = pel*4 + 0; + adja[2] = oel*4 + 3; + adja[3] = sel*4 + 1; + + iadr = (rel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = sel*4 + 0; + adja[1] = pel*4 + 2; + adja[2] = lel*4 + 3; + adja[3] = jel*4 + 2; + + iadr = (sel-1)*4 + 1; + adja = &mesh->adja[iadr]; + adja[0] = rel*4 + 0; + adja[1] = qel*4 + 3; + adja[3] = mel*4 + 2; + adja[2] = kel*4 + 3; + + /* remove 7 old tetra */ + for (k=1; k<=7; k++) { + pt0 = &mesh->tetra[list->tetra[k]/6]; + for(i=0 ; i<6 ; i++) { + MMG_edgePut(&hed,pt0->v[MMG_iare[i][0]],pt0->v[MMG_iare[i][1]],pt0->bdryinfo[i]); + } + MMG_delElt(mesh,list->tetra[k]/6); + } + + list->tetra[1] = jel; + list->tetra[2] = kel; + list->tetra[3] = lel; + list->tetra[4] = mel; + list->tetra[5] = nel; + list->tetra[6] = oel; + list->tetra[7] = pel; + list->tetra[8] = qel; + list->tetra[9] = rel; + list->tetra[10] = sel; + list->tetra[11] = 0; + MMG_updatebdryinfo(mesh,&hed,list); + M_free(hed.item); + +return(1); +} diff --git a/contrib/mmg3d/build/sources/swapar.c b/contrib/mmg3d/build/sources/swapar.c new file mode 100644 index 0000000000..043f858142 --- /dev/null +++ b/contrib/mmg3d/build/sources/swapar.c @@ -0,0 +1,106 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) { + pTetra pt; + int i,l,jel,ncas,ddebug; + + MMG_swpptr = 0; + ncas = 0; + if ( !MMG_getnElt(mesh,10) ) return(-1); + if(0 && list->tetra[1]/6==144988) ddebug=1; + else ddebug=0; + + switch(lon) { + case 3: + ncas = MMG_simu32(mesh,sol,list,crit); + break; + case 4: + ncas = MMG_simu44(mesh,sol,list,crit); + break; + case 5: + ncas = MMG_simu56(mesh,sol,list,crit); + break; + case 6: + ncas = MMG_simu68(mesh,sol,list,crit); + if(ddebug) printf("on vient avec %d\n",list->tetra[1]/6); + break; + case 7: + ncas = MMG_simu710(mesh,sol,list,crit); + break; + default: + return(0); + } + + if ( ncas && MMG_swpptr ) { + if(ddebug) MMG_saveMesh(mesh,"avt.mesh"); + for (l=1; l<=lon; l++) { + jel = list->tetra[l]/6; + pt = &mesh->tetra[jel]; + if(ddebug) { + printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3], + pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]); + } + MMG_kiudel(q,jel); + } + lon = MMG_swpptr(mesh,sol,list); + assert(lon); + if(!lon) return(0); + + for (l=1; l<=lon; l++) { + jel = list->tetra[l]; + pt = &mesh->tetra[jel]; + if ( pt->qual >= declic ) MMG_kiuput(q,jel); + for (i=0; i<4; i++) mesh->point[pt->v[i]].flag = mesh->flag; + } + if(ddebug) MMG_saveMesh(mesh,"sw.mesh"); + return(1); + } + + return(0); +} + diff --git a/contrib/mmg3d/build/sources/swaptet.c b/contrib/mmg3d/build/sources/swaptet.c new file mode 100644 index 0000000000..c9d75b00ed --- /dev/null +++ b/contrib/mmg3d/build/sources/swaptet.c @@ -0,0 +1,105 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define SCRIT 0.95 + +int MMG_swaptet(pMesh mesh,pSol sol,pQueue queue,double declic,int iel) { + pTetra pt,pt1; + List list; + double crit; + int i,*adja,iadr,lon,ier,adj,j,jel; + char tabar,done; + + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(0); + + /* mark internal edges */ + tabar = 0; + iadr = 4*(iel-1) + 1; + adja = &mesh->adja[iadr]; + for (i=0; i<4; i++) { + adj = adja[i] >> 2; + if ( !adj || pt->ref != mesh->tetra[adj].ref ) { + tabar |= 1 << MMG_iarf[i][0]; + tabar |= 1 << MMG_iarf[i][1]; + tabar |= 1 << MMG_iarf[i][2]; + } + } + if ( tabar == ALL_BDRY ) return(0); + + /* MMG_swap for anisotropy */ + done = 0; + for (i=0; i<6; i++) { + if ( tabar & 1<<i ) continue; + + lon = MMG_coquil(mesh,iel,i,&list); + if ( lon < 3 || lon > 7 ) continue; + + /* qual crit */ + crit = pt->qual; + for (j=2; j<=lon; j++) { + jel = list.tetra[j] / 6; + pt1 = &mesh->tetra[jel]; + crit = M_MAX(crit,pt1->qual); + } + crit *= SCRIT; + + ier = MMG_swapar(mesh,sol,queue,&list,lon,crit,declic); + if ( ier > 0 ) { + return(1); + break; + } + else if ( ier < 0 ) { + fprintf(stdout," ## UNABLE TO MMG_swap.\n"); + return(-1); + } + + } + + return(0); + +} diff --git a/contrib/mmg3d/build/sources/typelt.c b/contrib/mmg3d/build/sources/typelt.c new file mode 100644 index 0000000000..659c8eb033 --- /dev/null +++ b/contrib/mmg3d/build/sources/typelt.c @@ -0,0 +1,378 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +#define EPSVOL 0.001 +#define RAPMAX 0.25 + + +/* identify type of element : + ityp= 0: 4 faces bonnes (elt ok) + 1: 4 faces bonnes, vol nul (sliver) + 2: 4 faces ok, vol nul+sommet proche face (chapeau) + 3: 3 faces bonnes, 1 obtuse (aileron) + 4: 2 faces bonnes, 2 faces aigu => 1 petite arete + 5: 1 face bonne, 3 petites aretes + 6: 2 faces grandes aretes, 2 faces petites iaretes + 7: 4 faces grandes aretes + item: bad entity +*/ + + +/* nb face obtuse : nb faces aigu : +ityp : 0: 0 0 + 1: 0 0 + 2: 0 0 + 3: 1 0 + 4: 0 2 + 5: 0 3 + 6: 2 2 + 7: 0 4 +*/ +/* nb gde arete : nb petite arete : +ityp : 0: 0 0 + 1: 0 0 + 2: 0 0 + 3: 1 0 + 4: 0 1 + 5: 0 3 + 6: 1 1 + 7: 0 2 +*/ + +int MMG_typelt(pMesh mesh,int iel,int *item) { + pTetra pt; + pPoint pa,pb,pc,pd; + double abx,aby,abz,acx,acy,acz,adx,ady,adz,v1,v2,v3,vol; + double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz,h[6],volchk,ssmall; + double s[4],dd,rapmin,rapmax,surmin,surmax; + int i,k,ia,ib,ic,id,ityp,isur,isurmax,isurmin,iarmax,iarmin; + int nobtus,naigu; + short i0,i1,i2; + + ityp = 0; + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) return(-1); + + ia = pt->v[0]; + ib = pt->v[1]; + ic = pt->v[2]; + id = pt->v[3]; + pa = &mesh->point[ia]; + pb = &mesh->point[ib]; + pc = &mesh->point[ic]; + pd = &mesh->point[id]; + + /* volume */ + abx = pb->c[0] - pa->c[0]; + aby = pb->c[1] - pa->c[1]; + abz = pb->c[2] - pa->c[2]; + + acx = pc->c[0] - pa->c[0]; + acy = pc->c[1] - pa->c[1]; + acz = pc->c[2] - pa->c[2]; + + adx = pd->c[0] - pa->c[0]; + ady = pd->c[1] - pa->c[1]; + adz = pd->c[2] - pa->c[2]; + + v1 = acy*adz - acz*ady; + v2 = acz*adx - acx*adz; + v3 = acx*ady - acy*adx; + vol = abx * v1 + aby * v2 + abz * v3; + + /* max edge */ + h[0] = abx*abx + aby*aby + abz*abz; + h[1] = acx*acx + acy*acy + acz*acz; + h[2] = adx*adx + ady*ady + adz*adz; + + bcx = pc->c[0] - pb->c[0]; + bcy = pc->c[1] - pb->c[1]; + bcz = pc->c[2] - pb->c[2]; + + bdx = pd->c[0] - pb->c[0]; + bdy = pd->c[1] - pb->c[1]; + bdz = pd->c[2] - pb->c[2]; + + cdx = pd->c[0] - pc->c[0]; + cdy = pd->c[1] - pc->c[1]; + cdz = pd->c[2] - pc->c[2]; + + h[3] = bcx*bcx + bcy*bcy + bcz*bcz; + h[4] = bdx*bdx + bdy*bdy + bdz*bdz; + h[5] = cdx*cdx + cdy*cdy + cdz*cdz; + + /* face areas */ + dd = cdy*bdz - cdz*bdy; + s[0] = dd * dd; + dd = cdz*bdx - cdx*bdz; + s[0] = s[0] + dd * dd; + dd = cdx*bdy - cdy*bdx; + s[0] = s[0] + dd * dd; + s[0] = sqrt(s[0]); + + s[1] = sqrt(v1*v1 + v2*v2 + v3*v3); + + dd = bdy*adz - bdz*ady; + s[2] = dd * dd; + dd = bdz*adx - bdx*adz; + s[2] = s[2] + dd * dd; + dd = bdx*ady - bdy*adx; + s[2] = s[2] + dd * dd; + s[2] = sqrt(s[2]); + + dd = aby*acz - abz*acy; + s[3] = dd * dd; + dd = abz*acx - abx*acz; + s[3] = s[3] + dd * dd; + dd = abx*acy - aby*acx; + s[3] = s[3] + dd * dd; + s[3] = sqrt(s[3]); + + /* classification */ + rapmin = h[0]; + rapmax = h[0]; + iarmin = 0; + iarmax = 0; + for (i=1; i<6; i++) { + if ( h[i] < rapmin ) { + rapmin = h[i]; + iarmin = i; + } + else if ( h[i] > rapmax ) { + rapmax = h[i]; + iarmax = i; + } + } + rapmin = sqrt(rapmin); + rapmax = sqrt(rapmax); + volchk = EPSVOL * rapmin*rapmin*rapmin; + + /* small volume: types 1,2,3,4 */ + if ( vol < volchk ) { +//puts("volume nul : type 1,2,3,4"); + + ssmall = 0.4 * (s[0]+s[1]+s[2]+s[3]); + isur = 0; + for (i=0; i<4; i++) + isur += s[i] > ssmall; + + /* types 2,3 */ + item[0] = iarmax; + item[1] = MMG_isar[iarmax][0]; + if ( isur == 1 ) { + surmin = s[0]; + isurmin = 0; + surmax = s[0]; + isurmax = 0; + for (i=1; i<4; i++) { + if ( s[i] < surmin ) { + surmin = s[i]; + isurmin = i; + } + else if ( s[i] > surmax ) { + surmax = s[i]; + isurmax = i; + } + } + dd = surmin / surmax; + if ( dd < RAPMAX ) { + item[1] = MMG_isar[iarmax][0]; + return(3); + } + else { + item[0] = isurmax; + item[1] = isurmin; + return(2); + } + } + + /* types 1 */ + isur = 0; + if ( s[0]+s[1] > ssmall ) isur = 1; + if ( s[0]+s[2] > ssmall ) isur++; + if ( s[0]+s[3] > ssmall ) isur++; + + if ( isur > 2 ) { + dd = rapmin / rapmax; + item[0] = iarmin; + item[1] = MMG_idir[iarmin][0]; + if ( dd < 0.01 ) return(4); + if ( s[0]+s[1] > ssmall ) { + item[0] = 0; + return(1); + } + if ( s[0]+s[2] > ssmall ) { + item[0] = 1; + return(1); + } + if ( s[0]+s[3] > ssmall ) { + item[0] = 2; + return(1); + } + } + +//puts("default"); + item[0] = 0; + return(1); + }/*end chkvol*/ + + dd = rapmin / rapmax; + /* types 3,6,7 */ + if ( dd < RAPMAX ) { /*ie une arete 4 fois plus gde qu'une autre*/ + + for (i=0; i<6; i++) h[i] = sqrt(h[i]); + + nobtus = 0; + for (k=0; k<4; k++) { + for (i=0; i<3; i++) { + i0 = MMG_idir[k][i]; + i1 = MMG_idir[k][MMG_inxt[i]]; + i2 = MMG_idir[k][MMG_inxt[i+1]]; + if ( h[i0]+h[i1] < 1.2*h[i2] ) {/*1.4 ie une face obtus*/ + nobtus++; + item[0] = i2; + item[1] = MMG_idir[k][MMG_inxt[i+1]]; + } + } + } + + switch(nobtus){ + case 0 : + break; + case 1: + item[0] = iarmax; + item[1] = MMG_isar[iarmax][0]; + return(3); + case 2: + item[0] = iarmin; + item[1] = iarmax; + return(6); + default: + item[0] = iarmin; + item[1] = iarmax; +//printf("default obtus %d\n",nobtus); + return(7); + } + } + + /* type 4,5,7 */ + else if ( dd < 0.7*RAPMAX ) { + naigu = 0; + for (k=0; k<4; k++) { + for (i=0; i<3; i++) { + i0 = MMG_idir[k][i]; + i1 = MMG_idir[k][MMG_inxt[i]]; + i2 = MMG_idir[k][MMG_inxt[i+1]]; + if ( h[i0]+h[i1] > 1.5*h[i2] ) naigu++;/*1.5*/ + } + } + switch(naigu){ + case 0 : + break; + case 1: + break; + case 2: + item[0] = iarmin; + return(4); + case 3: +/*#warning definir item*/ + return(5); + default: + item[0] = iarmin; + item[1] = iarmax; +//printf("default aigu\n"); + return(7); + } + } + +// /* types 3,4,5,6,7 */ +// else { +// isur = 0; +// for (i=0; i<6; i++) { +// if ( h[i] < 2.0*rapmin ) isur++; +// } +// +// switch(isur){ +// case 2: +// puts("2 aretes tres grande retourne 7"); +// return(7); +// case 3: return(5); +// case 1: +// for (k=0; k<4; k++) { +// for (i=0; i<3; i++) { +// i0 = MMG_idir[k][i]; +// i1 = MMG_idir[k][i+1]; +// i2 = MMG_idir[k][i+2]; +// if ( h[i0]+h[i1] < 1.25*h[i2] ) return(6); +// } +// } +// puts("on retourne 4 la"); +// return(4); +// } +// } + +// surmin = s[0]; +// isurmin = 0; +// surmax = s[0]; +// isurmax = 0; +// for (i=1; i<4; i++) { +// if ( s[i] < surmin ) { +// surmin = s[i]; +// isurmin = i; +// } +// else if ( s[i] > surmax ) { +// surmax = s[i]; +// isurmax = i; +// } +// } +// +// item[0] = isurmax; +// item[1] = isurmin; + item[0] = 0; + //puts("default"); + return(1); +} diff --git a/contrib/mmg3d/build/sources/zaldy.c b/contrib/mmg3d/build/sources/zaldy.c new file mode 100644 index 0000000000..6bc7cd271c --- /dev/null +++ b/contrib/mmg3d/build/sources/zaldy.c @@ -0,0 +1,256 @@ +/**************************************************************************** +Logiciel initial: MMG3D Version 4.0 +Co-auteurs : Cecile Dobrzynski et Pascal Frey. +Propriétaires :IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +diffusé sous les termes et conditions de la licence publique générale de GNU +Version 3 ou toute version ultérieure. + +Ce fichier est une partie de MMG3D. +MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier +suivant les termes de la licence publique générale de GNU +Version 3 ou toute version ultérieure. +MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS +AUCUNE GARANTIE ; sans même garantie de valeur marchande. +Voir la licence publique générale de GNU pour plus de détails. +MMG3D est diffusé en espérant qu’il sera utile, +mais SANS AUCUNE GARANTIE, ni explicite ni implicite, +y compris les garanties de commercialisation ou +d’adaptation dans un but spécifique. +Reportez-vous à la licence publique générale de GNU pour plus de détails. +Vous devez avoir reçu une copie de la licence publique générale de GNU +en même temps que ce document. +Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>. +/**************************************************************************** +Initial software: MMG3D Version 4.0 +Co-authors: Cecile Dobrzynski et Pascal Frey. +Owners: IPB - UPMC -INRIA. + +Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, +spread under the terms and conditions of the license GNU General Public License +as published Version 3, or (at your option) any later version. + +This file is part of MMG3D +MMG3D is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. +MMG3D is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with MMG3D. If not, see <http://www.gnu.org/licenses/>. +****************************************************************************/ +#include "mesh.h" + +/* get new point address */ +int MMG_newPt(pMesh mesh,double c[3]) { + pPoint ppt; + int curpt; + + if ( !mesh->npnil ) return(0); + + curpt = mesh->npnil; + if ( mesh->npnil > mesh->np ) mesh->np = mesh->npnil; + ppt = &mesh->point[curpt]; + memcpy(ppt->c,c,3*sizeof(double)); + ppt->tag &= ~M_UNUSED; + mesh->npnil = ppt->tmp; + ppt->tmp = 0; + ppt->flag = mesh->flag; + + return(curpt); +} + + +void MMG_delPt(pMesh mesh,int ip) { + pPoint ppt; + ppt = &mesh->point[ip]; + memset(ppt,0,sizeof(Point)); + ppt->tag = M_UNUSED; + ppt->tmp = mesh->npnil; + mesh->npnil = ip; + if ( ip == mesh->np ) mesh->np--; +} + + +/* get new elt address */ +int MMG_newElt(pMesh mesh) { + int curiel; + + if ( !mesh->nenil ) { + fprintf(stdout," ## UNABLE TO ALLOCATE NEW ELEMENT.\n"); + return(0); + } + curiel = mesh->nenil; + if ( mesh->nenil > mesh->ne ) mesh->ne = mesh->nenil; + mesh->nenil = mesh->tetra[curiel].v[3]; + mesh->tetra[curiel].v[3] = 0; + + return(curiel); +} + + +void MMG_delElt(pMesh mesh,int iel) { + pTetra pt; + int iadr,i; + + pt = &mesh->tetra[iel]; + if ( !pt->v[0] ) { + fprintf(stdout," ## INVALID TETRA.\n"); + return; + } + memset(pt,0,sizeof(Tetra)); + pt->v[3] = mesh->nenil; + pt->qual = 0.0; + pt->edge = 0; + iadr = (iel-1)*4 + 1; + memset(&mesh->adja[iadr],0,4*sizeof(int)); + + mesh->nenil = iel; + if ( iel == mesh->ne ) mesh->ne--; +} + + +/* check if n elets available */ +int MMG_getnElt(pMesh mesh,int n) { + int curiel; + + if ( !mesh->nenil ) return(0); + curiel = mesh->nenil; + do { + curiel = mesh->tetra[curiel].v[3]; + } + while (--n); + + return(n == 0); +} + + +/* get new elt address */ +int MMG_newTria(pMesh mesh) { + int curiel; + + if ( !mesh->ntnil ) { + fprintf(stdout," ## UNABLE TO ALLOCATE NEW TRIANGLE.\n"); + return(0); + } + curiel = mesh->ntnil; + if ( mesh->ntnil > mesh->nt ) mesh->nt = mesh->ntnil; + mesh->ntnil = mesh->tria[curiel].v[2]; + mesh->tria[curiel].v[2] = 0; + + return(curiel); +} + + +void MMG_delTria(pMesh mesh,int iel) { + pTria pt; + + pt = &mesh->tria[iel]; + if ( !pt->v[0] ) { + fprintf(stdout," ## INVALID TRIANGLE.\n"); + return; + } + memset(pt,0,sizeof(Tria)); + pt->v[2] = mesh->ntnil; + mesh->ntnil = iel; + if ( iel == mesh->nt ) mesh->nt--; +} + + +/* allocate main structure */ +int MMG_zaldy(pMesh mesh) { + int million = 1048576L; + int k,npask; + + if ( mesh->info.memory < 0 ) { + mesh->npmax = M_MAX(1.5*mesh->np,NPMAX); + mesh->nemax = M_MAX(1.5*mesh->ne,NEMAX); + mesh->ntmax = M_MAX(1.5*mesh->nt,NTMAX); + } + else { + /* point+tria+tets+adja+sol+bucket+queue */ + int bytes = sizeof(Point) + 0.2*sizeof(Tria) \ + + 6*sizeof(Tetra) + 4*sizeof(int) \ + + sizeof(Sol) + sizeof(Displ) \ + + sizeof(int) + 5*sizeof(int); + + npask = (double)mesh->info.memory / bytes * million; + mesh->npmax = M_MAX(1.5*mesh->np,npask); + mesh->nemax = M_MAX(1.5*mesh->ne,6*npask); + mesh->ntmax = M_MAX(1.5*mesh->nt,(int)(0.3*npask)); + } + + mesh->point = (pPoint)M_calloc(mesh->npmax+1,sizeof(Point),"MMG_zaldy.point"); + assert(mesh->point); + mesh->tetra = (pTetra)M_calloc(mesh->nemax+1,sizeof(Tetra),"MMG_zaldy.tetra"); + assert(mesh->tetra); + mesh->tria = (pTria)M_calloc(mesh->ntmax+1,sizeof(Tria),"MMG_zaldy.tria"); + assert(mesh->tria); + mesh->adja = (int*)M_calloc(4*mesh->nemax+5,sizeof(int),"MMG_zaldy.adja"); + assert(mesh->adja); + mesh->disp = (pDispl)M_calloc(1,sizeof(Displ),"MMG_zaldy.displ"); + assert(mesh->disp); + mesh->disp->mv = (double*)M_calloc(3*(mesh->npmax + 1),sizeof(double),"MMG_zaldy.displ"); + assert(mesh->disp->mv); + mesh->disp->alpha = (short*)M_calloc(mesh->npmax+1,sizeof(short),"MMG_zaldy.displ"); + assert(mesh->disp->alpha); + + /* keep track of empty links */ + mesh->npnil = mesh->np + 1; + mesh->nenil = mesh->ne + 1; + + for (k=mesh->npnil; k<mesh->npmax-1; k++) + mesh->point[k].tmp = k+1; + + for (k=mesh->nenil; k<mesh->nemax-1; k++) + mesh->tetra[k].v[3] = k+1; + + if ( mesh->nt ) { + mesh->ntnil = mesh->nt + 1; + for (k=mesh->ntnil; k<mesh->ntmax-1; k++) + mesh->tria[k].v[2] = k+1; + } + + return(1); +} + + +/* sol structure */ +int MMG_zaldy3(pSol sol) { + if ( sol->npmax ) { + sol->met = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_zaldy3"); + assert(sol->met); + sol->metold = (double*)M_calloc(sol->npmax+1,sol->offset*sizeof(double),"MMG_zaldy3"); + assert(sol->metold); + } + + return(1); +} + + +/* edge structure for cavity */ +int MMG_zaldy4(pHedge hedg,int size) { + int k; + + hedg->size = size; + hedg->hnxt = size; + hedg->nhmax = (int)(16*size); + hedg->item = (hedge*)M_calloc(hedg->nhmax+1,sizeof(hedge),"MMG_zaldy4"); + //assert(hedg->item); + + for (k=size; k<hedg->nhmax; k++) + hedg->item[k].nxt = k+1; + + return(1); +} + + +/* internal edges */ +int MMG_zaldy5() { + return(1); +} + diff --git a/contrib/mpeg_encode/bframe.cpp b/contrib/mpeg_encode/bframe.cpp index 72eecb2deb..53a185dcd6 100644 --- a/contrib/mpeg_encode/bframe.cpp +++ b/contrib/mpeg_encode/bframe.cpp @@ -117,7 +117,7 @@ *==============*/ #include "all.h" -//#include <sys/param.h> +#include <string.h> #include <assert.h> #include "mtypes.h" #include "bitio.h" diff --git a/contrib/mpeg_encode/bitio.cpp b/contrib/mpeg_encode/bitio.cpp index 69b5303dea..1b78bff6a4 100644 --- a/contrib/mpeg_encode/bitio.cpp +++ b/contrib/mpeg_encode/bitio.cpp @@ -82,6 +82,7 @@ #include <assert.h> #include <time.h> #include <stdio.h> +#include <string.h> #include "all.h" #include "byteorder.h" #include "bitio.h" diff --git a/contrib/mpeg_encode/block.cpp b/contrib/mpeg_encode/block.cpp index f977a93fd0..9fa2f013f2 100644 --- a/contrib/mpeg_encode/block.cpp +++ b/contrib/mpeg_encode/block.cpp @@ -102,6 +102,7 @@ * HEADER FILES * *==============*/ +#include <string.h> #include "all.h" #include "mtypes.h" #include "frames.h" diff --git a/contrib/mpeg_encode/iframe.cpp b/contrib/mpeg_encode/iframe.cpp index 2fe01e7ec7..552c92489a 100644 --- a/contrib/mpeg_encode/iframe.cpp +++ b/contrib/mpeg_encode/iframe.cpp @@ -138,7 +138,7 @@ #include <time.h> -//#include <sys/param.h> +#include <string.h> #include "all.h" #include "mtypes.h" #include "frames.h" diff --git a/contrib/mpeg_encode/pframe.cpp b/contrib/mpeg_encode/pframe.cpp index 37ccb98cfb..7b6963d519 100644 --- a/contrib/mpeg_encode/pframe.cpp +++ b/contrib/mpeg_encode/pframe.cpp @@ -126,7 +126,7 @@ *==============*/ #include <assert.h> -//#include <sys/param.h> +#include <string.h> #include "all.h" #include "mtypes.h" #include "bitio.h" -- GitLab