Forked from
gmsh / gmsh
18762 commits behind the upstream repository.
-
Christophe Geuzaine authored
This patch fixes an old design flaw in the post-processing module, namely that we used a list of Post_View objects instead of a list of pointers to Post_View objects in CTX.post.list. This had many annoying consequences, in particular the fact that we needed to be extra careful every time the list was reallocated (as pointers to the list elements would become invalid). I tried very hard to change the code everywhere it should be changed, but I might have missed something. Please let me know if you see anything suspicious (like a crash when you duplicate/remove/combine/... post-processing views).
Christophe Geuzaine authoredThis patch fixes an old design flaw in the post-processing module, namely that we used a list of Post_View objects instead of a list of pointers to Post_View objects in CTX.post.list. This had many annoying consequences, in particular the fact that we needed to be extra careful every time the list was reallocated (as pointers to the list elements would become invalid). I tried very hard to change the code everywhere it should be changed, but I might have missed something. Please let me know if you see anything suspicious (like a crash when you duplicate/remove/combine/... post-processing views).
Skin.cpp 8.18 KiB
// $Id: Skin.cpp,v 1.29 2004-11-25 02:10:40 geuzaine Exp $
//
// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
//
// This program 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 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#include "Plugin.h"
#include "Skin.h"
#include "List.h"
#include "Tree.h"
#include "Views.h"
#include "Context.h"
#include "Malloc.h"
extern Context_T CTX;
List_T *GMSH_SkinPlugin::_list = NULL;
Tree_T *GMSH_SkinPlugin::_skin = NULL;
int *GMSH_SkinPlugin::_nbList = NULL;
int GMSH_SkinPlugin::_nbNod = 0;
int GMSH_SkinPlugin::_nbComp = 0;
int GMSH_SkinPlugin::_nbTimeStep = 0;
StringXNumber SkinOptions_Number[] = {
{GMSH_FULLRC, "iView", NULL, -1.}
};
extern "C"
{
GMSH_Plugin *GMSH_RegisterSkinPlugin()
{
return new GMSH_SkinPlugin();
}
}
GMSH_SkinPlugin::GMSH_SkinPlugin()
{
;
}
void GMSH_SkinPlugin::getName(char *name) const
{
strcpy(name, "Skin");
}
void GMSH_SkinPlugin::getInfos(char *author, char *copyright, char *help_text) const
{
strcpy(author, "C. Geuzaine (geuz@geuz.org)");
strcpy(copyright, "DGR (www.multiphysics.com)");
strcpy(help_text,
"Plugin(Skin) extracts the skin (the boundary) of\n"
"the view `iView'. If `iView' < 0, the plugin is run\n"
"on the current view.\n"
"\n"
"Plugin(Skin) creates one new view.\n");
}
int GMSH_SkinPlugin::getNbOptions() const
{
return sizeof(SkinOptions_Number) / sizeof(StringXNumber);
}
StringXNumber *GMSH_SkinPlugin::getOption(int iopt)
{
return &SkinOptions_Number[iopt];
}
void GMSH_SkinPlugin::catchErrorMessage(char *errorMessage) const
{
strcpy(errorMessage, "Skin failed...");
}
int GMSH_SkinPlugin::fcmpElm(const void *a, const void *b)
{
Elm *e1 = (Elm *)a, *e2 = (Elm *)b;
double s1, s2, TOL = CTX.lc * 1.e-12;
int i;
s1 = s2 = 0.0;
for(i = 0; i < _nbNod; i++) {
s1 += e1->coord[i];
s2 += e2->coord[i];
}
if(s1 - s2 > TOL)
return 1;
else if(s1 - s2 < -TOL)
return -1;
s1 = s2 = 0.0;
for(i = 0; i < _nbNod; i++) {
s1 += e1->coord[_nbNod + i];
s2 += e2->coord[_nbNod + i];
}
if(s1 - s2 > TOL)
return 1;
else if(s1 - s2 < -TOL)
return -1;
s1 = s2 = 0.0;
for(i = 0; i < _nbNod; i++) {
s1 += e1->coord[2 * _nbNod + i];
s2 += e2->coord[2 * _nbNod + i];
}
if(s1 - s2 > TOL)
return 1;
else if(s1 - s2 < -TOL)
return -1;
return 0;
}
void GMSH_SkinPlugin::addInView(void *a, void *b)
{
Elm *e = (Elm *)a;
for(int i = 0; i < 3 * _nbNod; i++)
List_Add(_list, &e->coord[i]);
for(int ts = 0; ts < _nbTimeStep; ts++)
for(int k = 0; k < _nbNod * _nbComp; k++)
List_Add(_list, &e->val[_nbNod * _nbComp * ts + k]);
Free(e->val);
(*_nbList)++;
}
void GMSH_SkinPlugin::skinList(List_T *inList, int inNbList,
int inNbNod, int inNbFac, int fxn[6][4])
{
if(!inNbList)
return;
int nb = List_Nbr(inList) / inNbList;
for(int i = 0; i < List_Nbr(inList); i += nb) {
double *coord = (double *)List_Pointer_Fast(inList, i);
double *val = (double *)List_Pointer_Fast(inList, i + 3 * inNbNod);
for(int j = 0; j < inNbFac; j++) {
Elm e, *pe;
for(int k = 0; k < _nbNod; k++) {
e.coord[k] = coord[fxn[j][k]]; // x
e.coord[_nbNod + k] = coord[inNbNod + fxn[j][k]]; // y
e.coord[2 * _nbNod + k] = coord[2 * inNbNod + fxn[j][k]]; // z
}
if(!(pe = (Elm *)Tree_PQuery(_skin, &e))) {
e.val = (double *)Malloc(_nbNod * _nbComp * _nbTimeStep * sizeof(double));
for(int k = 0; k < _nbNod; k++)
for(int ts = 0; ts < _nbTimeStep; ts++)
for(int n = 0; n < _nbComp; n++)
e.val[_nbNod * _nbComp * ts + _nbComp * k + n] =
val[inNbNod * _nbComp * ts + _nbComp * fxn[j][k] + n];
Tree_Add(_skin, &e);
}
else {
Free(pe->val);
Tree_Suppress(_skin, pe);
}
}
}
}
Post_View *GMSH_SkinPlugin::execute(Post_View * v)
{
int iView = (int)SkinOptions_Number[0].def;
if(iView < 0)
iView = v ? v->Index : 0;
if(!List_Pointer_Test(CTX.post.list, iView)) {
Msg(GERROR, "View[%d] does not exist", iView);
return v;
}
Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView);
Post_View *v2 = BeginView(1);
_nbTimeStep = v1->NbTimeStep;
int skinTri[6][4] = {{0,1,-1,-1}, {1,2,-1,-1}, {2,0,-1,-1}};
int skinQua[6][4] = {{0,1,-1,-1}, {1,2,-1,-1}, {2,3,-1,-1}, {3,0,-1,-1}};
int skinTet[6][4] = {{0,1,3,-1}, {0,2,1,-1}, {0,3,2,-1}, {1,2,3,-1}};
int skinHex[6][4] = {{0,1,5,4}, {0,3,2,1}, {0,4,7,3},
{1,2,6,5}, {2,3,7,6}, {4,5,6,7}};
int skinPri1[6][4] = {{0,1,4,3}, {0,3,5,2}, {1,2,5,4}};
int skinPri2[6][4] = {{0,2,1,-1}, {3,4,5,-1}};
int skinPyr1[6][4] = {{0,3,2,1}};
int skinPyr2[6][4] = {{0,1,4,-1}, {0,4,3,-1}, {1,2,4,-1}, {2,3,4,-1}};
// Generate lines
_nbNod = 2;
// scalar
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->SL; _nbList = &v2->NbSL; _nbComp = 1;
skinList(v1->ST, v1->NbST, 3, 3, skinTri);
skinList(v1->SQ, v1->NbSQ, 4, 4, skinQua);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// vector
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->VL; _nbList = &v2->NbVL; _nbComp = 3;
skinList(v1->VT, v1->NbVT, 3, 3, skinTri);
skinList(v1->VQ, v1->NbVQ, 4, 4, skinQua);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// tensor
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->TL; _nbList = &v2->NbTL; _nbComp = 9;
skinList(v1->TT, v1->NbTT, 3, 3, skinTri);
skinList(v1->TQ, v1->NbTQ, 4, 4, skinQua);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// Generate triangles
_nbNod = 3;
// scalar
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->ST; _nbList = &v2->NbST; _nbComp = 1;
skinList(v1->SS, v1->NbSS, 4, 4, skinTet);
skinList(v1->SI, v1->NbSI, 6, 2, skinPri2);
skinList(v1->SY, v1->NbSY, 5, 4, skinPyr2);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// vector
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->VT; _nbList = &v2->NbVT; _nbComp = 3;
skinList(v1->VS, v1->NbVS, 4, 4, skinTet);
skinList(v1->VI, v1->NbVI, 6, 2, skinPri2);
skinList(v1->VY, v1->NbVY, 5, 4, skinPyr2);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// tensor
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->TT; _nbList = &v2->NbTT; _nbComp = 9;
skinList(v1->TS, v1->NbTS, 4, 4, skinTet);
skinList(v1->TI, v1->NbTI, 6, 2, skinPri2);
skinList(v1->TY, v1->NbTY, 5, 4, skinPyr2);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// Generate quads
_nbNod = 4;
// scalar
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->SQ; _nbList = &v2->NbSQ; _nbComp = 1;
skinList(v1->SH, v1->NbSH, 8, 6, skinHex);
skinList(v1->SI, v1->NbSI, 6, 3, skinPri1);
skinList(v1->SY, v1->NbSY, 5, 1, skinPyr1);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// vector
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->VQ; _nbList = &v2->NbVQ; _nbComp = 3;
skinList(v1->VH, v1->NbVH, 8, 6, skinHex);
skinList(v1->VI, v1->NbVI, 6, 3, skinPri1);
skinList(v1->VY, v1->NbVY, 5, 1, skinPyr1);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// tensor
_skin = Tree_Create(sizeof(Elm), fcmpElm);
_list = v2->TQ; _nbList = &v2->NbTQ; _nbComp = 9;
skinList(v1->TH, v1->NbTH, 8, 6, skinHex);
skinList(v1->TI, v1->NbTI, 6, 3, skinPri1);
skinList(v1->TY, v1->NbTY, 5, 1, skinPyr1);
Tree_Action(_skin, addInView);
Tree_Delete(_skin);
// copy time data
for(int i = 0; i < List_Nbr(v1->Time); i++)
List_Add(v2->Time, List_Pointer(v1->Time, i));
// finalize
char name[1024], filename[1024];
sprintf(name, "%s_Skin", v1->Name);
sprintf(filename, "%s_Skin.pos", v1->Name);
EndView(v2, 1, filename, name);
return v2;
}