Forked from
gmsh / gmsh
21339 commits behind the upstream repository.
-
Christophe Geuzaine authoredChristophe Geuzaine authored
Views.cpp 26.94 KiB
// $Id: Views.cpp,v 1.27 2001-02-02 15:05:03 geuzaine Exp $
#include <set>
#include "Gmsh.h"
#include "Views.h"
#include "Context.h"
#include "ColorTable.h"
List_T *Post_ViewList = NULL;
Post_View *ActualView;
extern Context_T CTX ;
static int ActualViewNum=0;
static int NbPoints, NbLines, NbTriangles, NbTetrahedra;
/* ------------------------------------------------------------------------ */
/* V i e w s */
/* ------------------------------------------------------------------------ */
int fcmpPostViewNum(const void *v1, const void *v2){
return (((Post_View *)v1)->Num - ((Post_View *)v2)->Num);
}
int fcmpPostViewDuplicateOf(const void *v1, const void *v2){
return (((Post_View *)v1)->DuplicateOf - ((Post_View *)v2)->DuplicateOf);
}
void BeginView(int allocate){
ActualView = (Post_View*)Malloc(sizeof(Post_View));
NbPoints = NbLines = NbTriangles = NbTetrahedra = 0;
ActualView->NbSP = ActualView->NbVP = ActualView->NbTP = 0;
ActualView->NbSL = ActualView->NbVL = ActualView->NbTL = 0;
ActualView->NbST = ActualView->NbVT = ActualView->NbTT = 0;
ActualView->NbSS = ActualView->NbVS = ActualView->NbTS = 0;
if(allocate){
ActualView->datasize = sizeof(double);
ActualView->Time = List_Create(100,1000,sizeof(double));
ActualView->SP = List_Create(100,1000,sizeof(double));
ActualView->VP = List_Create(100,1000,sizeof(double));
ActualView->TP = List_Create(100,1000,sizeof(double));
ActualView->SL = List_Create(100,1000,sizeof(double));
ActualView->VL = List_Create(100,1000,sizeof(double));
ActualView->TL = List_Create(100,1000,sizeof(double));
ActualView->ST = List_Create(100,1000,sizeof(double));
ActualView->VT = List_Create(100,1000,sizeof(double));
ActualView->TT = List_Create(100,1000,sizeof(double));
ActualView->SS = List_Create(100,1000,sizeof(double));
ActualView->VS = List_Create(100,1000,sizeof(double));
ActualView->TS = List_Create(100,1000,sizeof(double));
}
else{
ActualView->Time = NULL;
ActualView->SP = NULL; ActualView->VP = NULL; ActualView->TP = NULL;
ActualView->SL = NULL; ActualView->VL = NULL; ActualView->TL = NULL;
ActualView->ST = NULL; ActualView->VT = NULL; ActualView->TT = NULL;
ActualView->SS = NULL; ActualView->VS = NULL; ActualView->TS = NULL;
}
ActualView->Changed = 1;
ActualView->Links = 0;
ActualView->DuplicateOf = 0;
ActualView->Min = 1.e200;
ActualView->Max = -1.e200;
ActualView->NbIso = CTX.post.initial_nbiso;
ActualView->IntervalsType = CTX.post.initial_intervals;
ActualView->Light = 0;
ActualView->ShowElement = 0;
ActualView->ShowTime = 1;
ActualView->Visible = CTX.post.initial_visibility;
ActualView->TimeStep = 0;
ActualView->ArrowScale = 100.;
ActualView->ArrowType = DRAW_POST_ARROW;
ActualView->ArrowLocation = DRAW_POST_LOCATE_COG;
ActualView->RangeType = DRAW_POST_DEFAULT;
ActualView->ShowScale = 1;
ActualView->TransparentScale = 1;
ActualView->ScaleType = DRAW_POST_LINEAR;
ActualView->Raise[0] = 0.0;
ActualView->Raise[1] = 0.0;
ActualView->Raise[2] = 0.0;
ActualView->ScalarOnly = 1;
ActualView->NbTimeStep = 0;
ActualView->CT.size = 255;
ActualView->CT.ipar[COLORTABLE_MODE] = COLORTABLE_RGB;
ActualView->normals = 0;
ColorTable_InitParam(1, &ActualView->CT, 1, 1);
ColorTable_Recompute(&ActualView->CT, 1, 1);
}
void Stat_ScalarSimplex(int nbnod, int N, double *V){
int i;
if(!NbPoints && !NbLines && !NbTriangles && !NbTetrahedra){
ActualView->Min = V[0];
ActualView->Max = V[0];
ActualView->NbTimeStep = N/nbnod;
}
else if(N/nbnod < ActualView->NbTimeStep)
ActualView->NbTimeStep = N/nbnod ;
for(i=0 ; i<N ; i++){
if(V[i] < ActualView->Min) ActualView->Min = V[i] ;
if(V[i] > ActualView->Max) ActualView->Max = V[i] ;
}
switch(nbnod){
case 1 : NbPoints++; break;
case 2 : NbLines++; break;
case 3 : NbTriangles++; break;
case 4 : NbTetrahedra++; break;
}
}
void Stat_VectorSimplex(int nbnod, int N, double *V){
double l0;
int i;
if(!NbPoints && !NbLines && !NbTriangles && !NbTetrahedra){
l0 = sqrt(DSQR(V[0])+DSQR(V[1])+DSQR(V[2]));
ActualView->Min = l0;
ActualView->Max = l0;
ActualView->NbTimeStep = N/(3*nbnod) ;
}
else if(N/(3*nbnod) < ActualView->NbTimeStep)
ActualView->NbTimeStep = N/(3*nbnod) ;
for(i=0 ; i<N ; i+=3){
l0 = sqrt(DSQR(V[i])+DSQR(V[i+1])+DSQR(V[i+2]));
if(l0 < ActualView->Min) ActualView->Min = l0 ;
if(l0 > ActualView->Max) ActualView->Max = l0 ;
}
ActualView->ScalarOnly = 0;
switch(nbnod){
case 1 : NbPoints++; break;
case 2 : NbLines++; break;
case 3 : NbTriangles++; break;
case 4 : NbTetrahedra++; break;
}
}
void Stat_TensorSimplex(int nbnod, int N, double *v){
Msg(GERROR, "Tensor Field Views not Implemented Yet");
}
void EndView(int AddInUI, int Number, char *FileName, char *Name,
double XOffset, double YOffset, double ZOffset){
int i, nb;
double d;
extern int AddViewInUI(int , char *, int);
// Points
if(ActualView->NbSP){
nb = List_Nbr(ActualView->SP) / ActualView->NbSP ;
for(i = 0 ; i < List_Nbr(ActualView->SP) ; i+=nb)
Stat_ScalarSimplex(1, nb-3, (double*)List_Pointer(ActualView->SP,i+3));
}
if(ActualView->NbVP){
nb = List_Nbr(ActualView->VP) / ActualView->NbVP ;
for(i = 0 ; i < List_Nbr(ActualView->VP) ; i+=nb)
Stat_VectorSimplex(1, nb-3, (double*)List_Pointer(ActualView->VP,i+3));
}
if(ActualView->NbTP){
nb = List_Nbr(ActualView->TP) / ActualView->NbTP ;
for(i = 0 ; i < List_Nbr(ActualView->TP) ; i+=nb)
Stat_TensorSimplex(1, nb-3, (double*)List_Pointer(ActualView->TP,i+3));
}
// Lines
if(ActualView->NbSL){
nb = List_Nbr(ActualView->SL) / ActualView->NbSL ;
for(i = 0 ; i < List_Nbr(ActualView->SL) ; i+=nb)
Stat_ScalarSimplex(2, nb-6, (double*)List_Pointer(ActualView->SL,i+6));
}
if(ActualView->NbVL){
nb = List_Nbr(ActualView->VL) / ActualView->NbVL ;
for(i = 0 ; i < List_Nbr(ActualView->VL) ; i+=nb)
Stat_VectorSimplex(2, nb-6, (double*)List_Pointer(ActualView->VL,i+6));
}
if(ActualView->NbTL){
nb = List_Nbr(ActualView->TL) / ActualView->NbTL ;
for(i = 0 ; i < List_Nbr(ActualView->TL) ; i+=nb)
Stat_TensorSimplex(2, nb-6, (double*)List_Pointer(ActualView->TL,i+6));
}
// Triangles
if(ActualView->NbST){
nb = List_Nbr(ActualView->ST) / ActualView->NbST ;
for(i = 0 ; i < List_Nbr(ActualView->ST) ; i+=nb)
Stat_ScalarSimplex(3, nb-9, (double*)List_Pointer(ActualView->ST,i+9));
}
if(ActualView->NbVT){
nb = List_Nbr(ActualView->VT) / ActualView->NbVT ;
for(i = 0 ; i < List_Nbr(ActualView->VT) ; i+=nb)
Stat_VectorSimplex(3, nb-9, (double*)List_Pointer(ActualView->VT,i+9));
}
if(ActualView->NbTT){
nb = List_Nbr(ActualView->TT) / ActualView->NbTT ;
for(i = 0 ; i < List_Nbr(ActualView->TT) ; i+=nb)
Stat_TensorSimplex(3, nb-9, (double*)List_Pointer(ActualView->TT,i+9));
}
// Tetrahedra
if(ActualView->NbSS){
nb = List_Nbr(ActualView->SS) / ActualView->NbSS ;
for(i = 0 ; i < List_Nbr(ActualView->SS) ; i+=nb)
Stat_ScalarSimplex(4, nb-12, (double*)List_Pointer(ActualView->SS,i+12));
}
if(ActualView->NbVS){
nb = List_Nbr(ActualView->VS) / ActualView->NbVS ;
for(i = 0 ; i < List_Nbr(ActualView->VS) ; i+=nb)
Stat_VectorSimplex(4, nb-12, (double*)List_Pointer(ActualView->VS,i+12));
}
if(ActualView->NbTS){
nb = List_Nbr(ActualView->TS) / ActualView->NbTS ;
for(i = 0 ; i < List_Nbr(ActualView->TS) ; i+=nb)
Stat_TensorSimplex(4, nb-12, (double*)List_Pointer(ActualView->TS,i+12));
}
// Dummy time values if using old parsed format...
if(!List_Nbr(ActualView->Time)){
for(i=0 ; i<ActualView->NbTimeStep ; i++){
d = (double)i;
List_Add(ActualView->Time, &d);
}
}
strcpy(ActualView->FileName,FileName);
strcpy(ActualView->Name,Name);
strcpy(ActualView->Format, "%.3e");
if(ActualView->Min > ActualView->Max)
ActualView->Min = ActualView->Max = 0.0 ;
ActualView->CustomMin = ActualView->Min;
ActualView->CustomMax = ActualView->Max;
ActualView->Offset[0] = XOffset*(CTX.range[0]?CTX.range[0]:CTX.lc)*1.e-3;
ActualView->Offset[1] = YOffset*(CTX.range[1]?CTX.range[1]:CTX.lc)*1.e-3;
ActualView->Offset[2] = ZOffset*(CTX.range[2]?CTX.range[2]:CTX.lc)*1.e-3;
/* j'en alloue directement le max pour eviter les problemes de
reallocation (avec CurrentView) */
if(!Post_ViewList)
Post_ViewList = List_Create(100,1,sizeof(Post_View));
if(!Number){
ActualView->Num = ++ActualViewNum;
List_Add(Post_ViewList,ActualView);
CTX.post.nb_views = List_Nbr(Post_ViewList);
if(AddInUI)
AddViewInUI(List_Nbr(Post_ViewList), ActualView->Name, ActualView->Num);
}
else{
ActualView->Num = Number;
List_Replace(Post_ViewList,ActualView,fcmpPostViewNum);
}
// it's a test, smoothing views in the volume !!!
// in the future, we'll have normals smoothed
if(CTX.post.smooth) ActualView->smooth();
ActualView = NULL;
}
bool FreeView(int num){
Post_View *v;
Msg(DEBUG, "Trying to free view %d",num);
if(num < 0 || num >= List_Nbr(Post_ViewList)){
return false ;
}
v = (Post_View*)List_Pointer(Post_ViewList, num);
FreeView(v);
List_Suppress(Post_ViewList, v, fcmpPostViewNum);
CTX.post.nb_views = List_Nbr(Post_ViewList);
Msg(INFO, "View %d deleted (%d views left)",num, List_Nbr(Post_ViewList));
return true;
}
void FreeView(Post_View *v){
Post_View vv,*v2;
int free = 1;
if(v->DuplicateOf){
vv.Num = v->DuplicateOf ;
Msg(DEBUG, "This View is a Duplicata");
if(!(v2 = (Post_View*)List_PQuery(Post_ViewList, &vv, fcmpPostViewNum))){
Msg(DEBUG, " ->The Original View is Gone");
if(!(v2 = (Post_View*)List_PQuery(Post_ViewList, v, fcmpPostViewDuplicateOf))){
Msg(DEBUG, " ->There are no other duplicata");
free = 1 ;
}
else{
free = 0 ;
}
}
else{
v2->Links--;
free = 0 ;
Msg(DEBUG, " ->The original still exists, so I dont't free anything now");
}
}
if(v->Links)
Msg(DEBUG, " ->This view is linked: Cannot free");
if(free && !v->Links){
Msg(DEBUG, " ->Freeing View");
List_Delete(v->Time);
List_Delete(v->SP); List_Delete(v->VP); List_Delete(v->TP);
List_Delete(v->SL); List_Delete(v->VL); List_Delete(v->TL);
List_Delete(v->ST); List_Delete(v->VT); List_Delete(v->TT);
List_Delete(v->SS); List_Delete(v->VS); List_Delete(v->TS);
}
v->reset_normals();
}
void CopyViewOptions(Post_View *src, Post_View *dest){
strcpy(dest->Format, src->Format);
dest->CustomMin = src->CustomMin;
dest->CustomMax = src->CustomMax;
dest->Offset[0] = src->Offset[0];
dest->Offset[1] = src->Offset[1];
dest->Offset[2] = src->Offset[2];
dest->Raise[0] = src->Raise[0];
dest->Raise[1] = src->Raise[1];
dest->Raise[2] = src->Raise[2];
dest->ArrowScale = src->ArrowScale;
dest->Visible = src->Visible;
dest->IntervalsType = src->IntervalsType;
dest->NbIso = src->NbIso;
dest->Light = src->Light ;
dest->ShowElement = src->ShowElement;
dest->ShowTime = src->ShowTime;
dest->ShowScale = src->ShowScale;
dest->TransparentScale = src->TransparentScale;
dest->ScaleType = src->ScaleType;
dest->RangeType = src->RangeType;
dest->ArrowType = src->ArrowType;
dest->ArrowLocation = src->ArrowLocation;
dest->TimeStep = src->TimeStep;
ColorTable_Copy(&src->CT);
ColorTable_Paste(&dest->CT);
}
char *Get_StringViewOption(int num, char *str, int *type){
Post_View *v;
if(num < 0 || num >= List_Nbr(Post_ViewList)){
*type = -1 ;
return NULL ;
}
v = (Post_View*)List_Pointer(Post_ViewList, num);
if(!strcmp(str, "Format")) return v->Format ;
else if(!strcmp(str, "FileName")) return v->FileName ;
else if(!strcmp(str, "Name")) return v->Name ;
else return NULL ;
}
void Print_StringViewOptions(int num, FILE *file){
Post_View *v;
if(num < 0 || num >= List_Nbr(Post_ViewList))
return ;
v = (Post_View*)List_Pointer(Post_ViewList, num);
fprintf(file, "PostProcessing.View[%d].Format = \"%s\";\n", num, v->Format);
fprintf(file, "PostProcessing.View[%d].FileName = \"%s\";\n", num, v->FileName);
fprintf(file, "PostProcessing.View[%d].Name = \"%s\";\n", num, v->Name);
}
void *Get_NumberViewOption(int num, char *str, int *type){
Post_View *v;
if(num < 0 || num >= List_Nbr(Post_ViewList)){
*type = -1 ;
return NULL ;
}
v = (Post_View*)List_Pointer(Post_ViewList, num);
if(!strcmp(str, "NbTimeStep")) { *type = GMSH_INT; return (void*)&v->NbTimeStep; }
else if(!strcmp(str, "TimeStep")) { *type = GMSH_INT; return (void*)&v->TimeStep; }
else if(!strcmp(str, "Min")) { *type = GMSH_DOUBLE; return (void*)&v->Min ; }
else if(!strcmp(str, "Max")) { *type = GMSH_DOUBLE ; return (void*)&v->Max ; }
else if(!strcmp(str, "CustomMin")) { *type = GMSH_DOUBLE ; return (void*)&v->CustomMin ; }
else if(!strcmp(str, "CustomMax")) { *type = GMSH_DOUBLE ; return (void*)&v->CustomMax ; }
else if(!strcmp(str, "Offset0")) { *type = GMSH_DOUBLE ; return (void*)&v->Offset[0] ; }
else if(!strcmp(str, "Offset1")) { *type = GMSH_DOUBLE ; return (void*)&v->Offset[1] ; }
else if(!strcmp(str, "Offset2")) { *type = GMSH_DOUBLE ; return (void*)&v->Offset[2] ; }
else if(!strcmp(str, "Raise0")) { *type = GMSH_DOUBLE ; return (void*)&v->Raise[0] ; }
else if(!strcmp(str, "Raise1")) { *type = GMSH_DOUBLE ; return (void*)&v->Raise[1] ; }
else if(!strcmp(str, "Raise2")) { *type = GMSH_DOUBLE ; return (void*)&v->Raise[2] ; }
else if(!strcmp(str, "ArrowScale")) { *type = GMSH_DOUBLE ; return (void*)&v->ArrowScale ; }
else if(!strcmp(str, "Visible")) { *type = GMSH_INT ; return (void*)&v->Visible ; }
else if(!strcmp(str, "IntervalsType")) { *type = GMSH_INT ; return (void*)&v->IntervalsType ; }
else if(!strcmp(str, "NbIso")) { *type = GMSH_INT ; return (void*)&v->NbIso ; }
else if(!strcmp(str, "Light")) { *type = GMSH_INT ; return (void*)&v->Light ; }
else if(!strcmp(str, "ShowElement")) { *type = GMSH_INT ; return (void*)&v->ShowElement ; }
else if(!strcmp(str, "ShowTime")) { *type = GMSH_INT ; return (void*)&v->ShowTime ; }
else if(!strcmp(str, "ShowScale")) { *type = GMSH_INT ; return (void*)&v->ShowScale ; }
else if(!strcmp(str, "TransparentScale")) { *type = GMSH_INT ; return (void*)&v->TransparentScale ; }
else if(!strcmp(str, "ScaleType")) { *type = GMSH_INT ; return (void*)&v->ScaleType ; }
else if(!strcmp(str, "RangeType")) { *type = GMSH_INT ; return (void*)&v->RangeType ; }
else if(!strcmp(str, "ArrowType")) { *type = GMSH_INT ; return (void*)&v->ArrowType ; }
else if(!strcmp(str, "ArrowLocation")) { *type = GMSH_INT ; return (void*)&v->ArrowLocation ; }
else{
return NULL ;
}
}
void Print_NumberViewOptions(int num, FILE *file){
Post_View *v;
if(num < 0 || num >= List_Nbr(Post_ViewList))
return ;
v = (Post_View*)List_Pointer(Post_ViewList, num);
fprintf(file, "PostProcessing.View[%d].NbTimeStep = %d;\n", num, v->NbTimeStep);
fprintf(file, "PostProcessing.View[%d].TimeStep = %d;\n", num, v->TimeStep);
fprintf(file, "PostProcessing.View[%d].Min = %g;\n", num, v->Min);
fprintf(file, "PostProcessing.View[%d].Max = %g;\n", num, v->Max);
fprintf(file, "PostProcessing.View[%d].CustomMin = %g;\n", num, v->CustomMin);
fprintf(file, "PostProcessing.View[%d].CustomMax = %g;\n", num, v->CustomMax);
fprintf(file, "PostProcessing.View[%d].ArrowScale = %g;\n", num, v->ArrowScale);
fprintf(file, "PostProcessing.View[%d].Visible = %d;\n", num, v->Visible);
fprintf(file, "PostProcessing.View[%d].IntervalsType = %d;\n", num, v->IntervalsType);
fprintf(file, "PostProcessing.View[%d].NbIso = %d;\n", num, v->NbIso);
fprintf(file, "PostProcessing.View[%d].Light = %d;\n", num, v->Light);
fprintf(file, "PostProcessing.View[%d].ShowElement = %d;\n", num, v->ShowElement);
fprintf(file, "PostProcessing.View[%d].ShowTime = %d;\n", num, v->ShowTime);
fprintf(file, "PostProcessing.View[%d].ShowScale = %d;\n", num, v->ShowScale);
fprintf(file, "PostProcessing.View[%d].TransparentScale = %d;\n", num, v->TransparentScale);
fprintf(file, "PostProcessing.View[%d].ScaleType = %d;\n", num, v->ScaleType);
fprintf(file, "PostProcessing.View[%d].RangeType = %d;\n", num, v->RangeType);
fprintf(file, "PostProcessing.View[%d].ArrowType = %d;\n", num, v->ArrowType);
fprintf(file, "PostProcessing.View[%d].ArrowLocation = %d;\n", num, v->ArrowLocation);
fprintf(file, "PostProcessing.View[%d].Offset0 = %g;\n", num, v->Offset[0]);
fprintf(file, "PostProcessing.View[%d].Offset1 = %g;\n", num, v->Offset[1]);
fprintf(file, "PostProcessing.View[%d].Offset2 = %g;\n", num, v->Offset[2]);
fprintf(file, "PostProcessing.View[%d].Raise0 = %g;\n", num, v->Raise[0]);
fprintf(file, "PostProcessing.View[%d].Raise1 = %g;\n", num, v->Raise[1]);
fprintf(file, "PostProcessing.View[%d].Raise2 = %g;\n", num, v->Raise[2]);
fprintf(file, "PostProcessing.View[%d].Color = { ", num);
ColorTable_Print(&v->CT, file);
fprintf(file, " };\n");
}
ColorTable *Get_ColorTableViewOption(int num){
Post_View *v;
if(num < 0 || num >= List_Nbr(Post_ViewList))
return NULL ;
v = (Post_View*)List_Pointer(Post_ViewList, num);
return &v->CT ;
}
/* ------------------------------------------------------------------------ */
/* R e a d _ V i e w */
/* ------------------------------------------------------------------------ */
extern int Force_ViewNumber;
void Read_View(FILE *file, char *filename){
char str[NAME_STR_L], name[NAME_STR_L];
int nb, format, size, testone, swap;
double version;
while (1) {
do {
fgets(str, NAME_STR_L, file) ;
if (feof(file)) break ;
} while (str[0] != '$') ;
if (feof(file)) break ;
/* F o r m a t */
if (!strncmp(&str[1], "PostFormat", 10)){
fscanf(file, "%lf %d %d\n", &version, &format, &size) ;
if(version < 1.0){
Msg(GERROR, "The Version of this File is too old (%g < 1.0)", version);
return;
}
if(size == sizeof(double))
Msg(DEBUG, "Data is in Double Precision Format (size==%d)", size);
else if(size == sizeof(float))
Msg(DEBUG, "Data is in Single Precision Format (size==%d)", size);
else{
Msg(GERROR, "Unknown Type of Data (Size = %d) in Post-Processing File",
size);
return;
}
if(format == 0)
format = LIST_FORMAT_ASCII ;
else if(format == 1)
format = LIST_FORMAT_BINARY ;
else{
Msg(GERROR, "Unknown Format for View");
return ;
}
}
/* V i e w */
if (!strncmp(&str[1], "View", 4)) {
BeginView(0);
fscanf(file, "%s %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
name, &ActualView->NbTimeStep,
&ActualView->NbSP, &ActualView->NbVP, &ActualView->NbTP,
&ActualView->NbSL, &ActualView->NbVL, &ActualView->NbTL,
&ActualView->NbST, &ActualView->NbVT, &ActualView->NbTT,
&ActualView->NbSS, &ActualView->NbVS, &ActualView->NbTS);
swap = 0 ;
if(format == LIST_FORMAT_BINARY){
fread(&testone, sizeof(int), 1, file);
if(testone != 1){
Msg(INFO, "Swapping Bytes from Binary File");
swap = 1;
}
}
ActualView->datasize = size ;
// Time values
ActualView->Time = List_CreateFromFile(ActualView->NbTimeStep,
size, file, format, swap);
// Points
nb = ActualView->NbSP ? ActualView->NbSP * (ActualView->NbTimeStep +3) : 0 ;
ActualView->SP = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbVP ? ActualView->NbVP * (ActualView->NbTimeStep*3+3) : 0 ;
ActualView->VP = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbTP ? ActualView->NbTP * (ActualView->NbTimeStep*9+3) : 0 ;
ActualView->TP = List_CreateFromFile(nb, size, file, format, swap);
// Lines
nb = ActualView->NbSL ? ActualView->NbSL * (ActualView->NbTimeStep*2 +6) : 0 ;
ActualView->SL = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbVL ? ActualView->NbVL * (ActualView->NbTimeStep*2*3+6) : 0 ;
ActualView->VL = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbTL ? ActualView->NbTL * (ActualView->NbTimeStep*2*9+6) : 0 ;
ActualView->TL = List_CreateFromFile(nb, size, file, format, swap);
// Triangles
nb = ActualView->NbST ? ActualView->NbST * (ActualView->NbTimeStep*3 +9) : 0 ;
ActualView->ST = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbVT ? ActualView->NbVT * (ActualView->NbTimeStep*3*3+9) : 0 ;
ActualView->VT = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbTT ? ActualView->NbTT * (ActualView->NbTimeStep*3*9+9) : 0 ;
ActualView->TT = List_CreateFromFile(nb, size, file, format, swap);
// Tetrahedra
nb = ActualView->NbSS ? ActualView->NbSS * (ActualView->NbTimeStep*4 +12) : 0 ;
ActualView->SS = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbVS ? ActualView->NbVS * (ActualView->NbTimeStep*4*3+12) : 0 ;
ActualView->VS = List_CreateFromFile(nb, size, file, format, swap);
nb = ActualView->NbTS ? ActualView->NbTS * (ActualView->NbTimeStep*4*9+12) : 0 ;
ActualView->TS = List_CreateFromFile(nb, size, file, format, swap);
Msg(DEBUG, "Read View '%s' (%d TimeSteps): %d %d %d %d %d %d %d %d %d %d %d %d",
name, ActualView->NbTimeStep,
ActualView->NbSP, ActualView->NbVP, ActualView->NbTP,
ActualView->NbSL, ActualView->NbVL, ActualView->NbTL,
ActualView->NbST, ActualView->NbVT, ActualView->NbTT,
ActualView->NbSS, ActualView->NbVS, ActualView->NbTS);
Msg(DEBUG, "List_Nbrs: %d %d %d %d %d %d %d %d %d %d %d %d",
List_Nbr(ActualView->SP), List_Nbr(ActualView->VP), List_Nbr(ActualView->TP),
List_Nbr(ActualView->SL), List_Nbr(ActualView->VL), List_Nbr(ActualView->TL),
List_Nbr(ActualView->ST), List_Nbr(ActualView->VT), List_Nbr(ActualView->TT),
List_Nbr(ActualView->SS), List_Nbr(ActualView->VS), List_Nbr(ActualView->TS));
EndView(1, Force_ViewNumber, filename, name, 0., 0., 0.);
}
do {
fgets(str, NAME_STR_L, file) ;
if (feof(file)) Msg(GERROR,"Prematured End of File");
} while (str[0] != '$') ;
} /* while 1 ... */
}
/*
A little util for smoothing a view.
*/
using namespace std;
struct xyzv
{
private:
public:
double x,y,z,*vals;
int nbvals;
int nboccurences;
static double eps;
void update (int nbVals, double *);
xyzv(double x, double y, double z);
~xyzv();
xyzv & operator = ( const xyzv &);
xyzv ( const xyzv &);
};
double xyzv::eps = 0.0;
xyzv::xyzv (double xx, double yy, double zz) : x(xx),y(yy),z(zz),vals(0),nbvals(0),nboccurences(0){}
xyzv::~xyzv()
{
if(vals)delete [] vals;
}
xyzv::xyzv(const xyzv &other)
{
x = other.x;
y = other.y;
z = other.z;
nbvals = other.nbvals;
nboccurences = other.nboccurences;
if(other.vals && other.nbvals)
{
vals = new double[other.nbvals];
for(int i=0;i<nbvals;i++)vals[i] = other.vals[i];
}
}
xyzv & xyzv::operator = (const xyzv &other)
{
if(this != &other)
{
x = other.x;
y = other.y;
z = other.z;
nbvals = other.nbvals;
nboccurences = other.nboccurences;
if(other.vals && other.nbvals)
{
vals = new double[other.nbvals];
for(int i=0;i<nbvals;i++)vals[i] = other.vals[i];
}
}
return *this;
}
void xyzv::update (int n, double *v)
{
int i;
if(!vals)
{
vals = new double[n];
for(i=0;i<nbvals;i++)vals[i] = 0.0;
nbvals = n;
nboccurences = 0;
}
else if (nbvals != n)
{
throw n;
}
// if(n==3)printf("val(%d,%f,%f,%f) = %f %f %f\n",nboccurences,x,y,z,v[0],v[1],v[2]);
double x1 = (double)(nboccurences)/ (double)(nboccurences + 1);
double x2 = 1./(double)(nboccurences + 1);
for(i=0;i<nbvals;i++)vals[i] = (x1 * vals[i] + x2 * v[i]);
nboccurences++;
}
struct lessthanxyzv
{
bool operator () (const xyzv & p2, const xyzv &p1) const
{
if( p1.x - p2.x > xyzv::eps)return true;
if( p1.x - p2.x <-xyzv::eps)return false;
if( p1.y - p2.y > xyzv::eps)return true;
if( p1.y - p2.y <-xyzv::eps)return false;
if( p1.z - p2.z > xyzv::eps)return true;
return false;
}
};
typedef set<xyzv,lessthanxyzv> mycont;
typedef mycont::const_iterator iter;
class smooth_container
{
public :
mycont c;
};
void smooth_list (List_T *SS ,
int NbTimeStep,
int nbvert,
int nb,
mycont & connectivities)
{
double *x,*y,*z,*v;
int i,j,k;
double *vals = new double[NbTimeStep];
for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
{
x = (double*)List_Pointer_Fast(SS,i);
y = (double*)List_Pointer_Fast(SS,i+nbvert);
z = (double*)List_Pointer_Fast(SS,i+2*nbvert);
v = (double*)List_Pointer_Fast(SS,i+3*nbvert);
for(j=0;j<nbvert;j++)
{
for(k=0;k<NbTimeStep;k++)vals[k] = v[j+k*8];
xyzv x(x[j],y[j],z[j]);
iter it = connectivities.find(x);
if(it == connectivities.end())
{
x.update(NbTimeStep,vals);
connectivities.insert(x);
}
else
{
xyzv *xx = (xyzv*) &(*it); // a little weird ... becaus we know that
// this will not destroy the set ordering
xx->update(NbTimeStep,vals);
}
}
}
for(i = 0 ; i < List_Nbr(SS) ; i+=nb)
{
x = (double*)List_Pointer_Fast(SS,i);
y = (double*)List_Pointer_Fast(SS,i+nbvert);
z = (double*)List_Pointer_Fast(SS,i+2*nbvert);
v = (double*)List_Pointer_Fast(SS,i+3*nbvert);
for(j=0;j<nbvert;j++)
{
xyzv xyz(x[j],y[j],z[j]);
//double l = sqrt((x[j])*(x[j]) + y[j]*y[j] + z[j] * z[j]);
iter it = connectivities.find(xyz);
for(k=0;k<NbTimeStep;k++)v[j+k*8] = (*it).vals[k];
//for(k=0;k<NbTimeStep;k++)v[j+k*8] = l;
}
}
delete [] vals;
}
void Post_View :: smooth ()
{
xyzv::eps = CTX.lc * 1.e-6;
int nb;
if(NbSS){
mycont conSS;
Msg(INFO,"Smoothing SS vector in a view ...");
nb = List_Nbr(SS) / NbSS ;
smooth_list (SS , NbTimeStep, 4, nb, conSS);
Msg(INFO,"...done");
}
if(NbST){
mycont conST;
Msg(INFO,"Smoothing ST vector in a view ...");
nb = List_Nbr(ST) / NbST ;
smooth_list (ST , NbTimeStep, 3, nb, conST);
Msg(INFO,"...done");
}
}
/*
Another util to smooth normals
*/
void Post_View :: reset_normals()
{
if(normals)delete normals;
normals = 0;
}
void Post_View :: add_normal(double x, double y, double z,
double nx, double ny, double nz)
{
if(!normals)normals = new smooth_container;
xyzv xyz(x,y,z);
double n[3] = {nx,ny,nz};
iter it = normals->c.find(xyz);
if(it == normals->c.end())
{
xyz.update(3,n);
normals->c.insert(xyz);
}
else
{
xyzv *xx = (xyzv*) &(*it);
xx->update(3,n);
}
}
bool Post_View :: get_normal(double x, double y, double z,
double &nx, double &ny, double &nz)
{
if(!normals)
return false;
xyzv xyz(x,y,z);
iter it = normals->c.find(xyz);
if(it == normals->c.end())return false;
nx = (*it).vals[0];
ny = (*it).vals[1];
nz = (*it).vals[2];
return true;
}