#include "../elmerpost.h"
typedef struct arrow_s
{
scalar_t *VectorData[4];
scalar_t *ColorData;
scalar_t *LengthData;
scalar_t *ThresholdData;
arrow_style_t Style;
double Floor,Ceiling;
double RadiusScale,LengthScale;
logical_t EqualLength,EqualRadius;
material_t *Material;
colormap_t *ColorMap;
int LineQuality;
line_style_t LineStyle;
} arrow_t;
static int vis_arrow( geometry_t *geometry, element_model_t *model, arrow_t *Arrows,double dt )
{
line_style_t line_style = Arrows->LineStyle;
arrow_style_t arrow_style = Arrows->Style;
vertex_t *v = geometry->Vertices;
int i,N=geometry->VertexCount,quick;
float x[3];
vertex_face_t *face;
element_t *elements = model->Elements;
double LScl,CScl,CAdd,vx,vy,vz,co;
double R,RadiusScale,L,LengthScale;
void gra_set_colormap(), gra_sphere_quality(), gra_set_material(), gra_arrow() ;
if ( !Arrows->VectorData ||
!Arrows->VectorData[1]->f || !Arrows->VectorData[2]->f || !Arrows->VectorData[3]->f
)
{
return TRUE;
}
if ( !GlobalOptions.StereoMode )
if ( Arrows->Material->Diffuse[3] < 1.0 )
{
if ( GlobalPass != 0 ) return TRUE;
} else if ( GlobalPass == 0 )
{
return TRUE;
}
LengthScale = Arrows->LengthScale / 10.0;
RadiusScale = Arrows->RadiusScale / 10.0;
if ( Arrows->LengthData && Arrows->LengthData->f )
{
LScl = 0.05;
if ( ABS( Arrows->LengthData->max - Arrows->LengthData->min ) > 1.0E-10 )
LScl = 1.0 / (Arrows->LengthData->max - Arrows->LengthData->min);
}
if ( Arrows->ColorData && Arrows->ColorData->f )
{
CAdd = Arrows->ColorData->min;
CScl = 1.0 / ( Arrows->ColorData->max - Arrows->ColorData->min );
gra_set_colormap( Arrows->ColorMap );
} else gra_set_colormap( NULL );
quick = epMouseDown && epMouseDownTakesTooLong;
if ( quick )
{
line_style = line_style_line;
arrow_style = arrow_style_stick;
gra_line_width( 1.0 );
} else
{
if ( line_style == line_style_cylinder )
gra_sphere_quality( Arrows->LineQuality );
else
gra_line_width( Arrows->RadiusScale );
}
gra_set_material( Arrows->Material );
for( i=0; i<N; i++,v++ )
{
if ( !v->ElementModelNode ) continue;
for( face=v->Faces; face!=NULL; face=face->Next )
{
if ( geometry->Triangles[face->Face].Element->DisplayFlag ) break;
}
#if 1
if ( v->Faces && !face ) continue;
#else
if ( !face ) continue;
#endif
if ( Arrows->ThresholdData && Arrows->ThresholdData->f )
{
if ( Arrows->ThresholdData->f[i] < Arrows->Floor ||
Arrows->ThresholdData->f[i] > Arrows->Ceiling ) continue;
}
vx = Arrows->VectorData[1]->f[i];
vy = Arrows->VectorData[2]->f[i];
vz = Arrows->VectorData[3]->f[i];
L = sqrt( vx*vx + vy*vy + vz*vz );
if ( L < 1.0E-10 ) continue;
L = LengthScale / L;
R = LengthScale * RadiusScale;
if ( Arrows->ColorData && Arrows->ColorData->f )
{
co = CScl*(Arrows->ColorData->f[i]-CAdd);
}
x[0] = L*vx;
x[1] = L*vy;
x[2] = L*vz;
if ( !Arrows->EqualLength && Arrows->LengthData && Arrows->LengthData->f )
{
x[0] *= LScl*Arrows->LengthData->f[i];
x[1] *= LScl*Arrows->LengthData->f[i];
x[2] *= LScl*Arrows->LengthData->f[i];
if ( !Arrows->EqualRadius )
{
R *= LScl*Arrows->LengthData->f[i];
}
}
gra_arrow( v->x,x,co,line_style,arrow_style,R );
if ( epMouseDown && (i & 8) )
{
if ( !epMouseDownTakesTooLong )
{
if ( RealTime() - dt > TooLong1 )
{
++epMouseDownTakesTooLong;
return FALSE;
}
}
else if ( RealTime() - dt > TooLong2 )
if ( ++epMouseDownTakesTooLong > 3 )
{
return FALSE;
} else dt = RealTime();
}
if ( BreakLoop ) break;
}
return TRUE;
}
static arrow_t *vis_arrow_alloc()
{
arrow_t *arrow = (arrow_t *)calloc(sizeof(arrow_t),1);
if ( !arrow )
{
fprintf( stderr, "vis_arrow_alloc: FATAL: can't alloc a few bytes of memory\n" );
}
return arrow;
}
static void vis_arrow_delete(arrow_t *arrow)
{
if ( arrow ) free( arrow );
}
int vis_initialize_arrow_visual()
{
static char *visual_name = "Arrows";
visual_type_t VisualDef;
static arrow_t arrow;
static visual_param_t ArrowParams[] =
{
{ "VectorData0", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "VectorData1", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "VectorData2", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "VectorData3", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "ColorData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "LengthData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "ThresholdData", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, NULL },
{ "Style", "%d", 0, VIS_VISUAL_PARAM_INT, arrow_style_arrow, 0.0, NULL },
{ "Floor", "%lf", 0, VIS_VISUAL_PARAM_FLOAT, 0, 0.0, NULL },
{ "Ceiling", "%lf", 0, VIS_VISUAL_PARAM_FLOAT, 0, 1.0, NULL },
{ "RadiusScale", "%lf", 0, VIS_VISUAL_PARAM_FLOAT, 0, 1.0, NULL },
{ "LengthScale", "%lf", 0, VIS_VISUAL_PARAM_FLOAT, 0, 1.0, NULL },
{ "EqualLength", "%c", 0, VIS_VISUAL_PARAM_LOGICAL, 1, 0.0, NULL },
{ "EqualRadius", "%c", 0, VIS_VISUAL_PARAM_LOGICAL, 0, 0.0, NULL },
{ "Material", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultMaterial },
{ "ColorMap", "%s", 0, VIS_VISUAL_PARAM_POINTER, 0, 0.0, &DefaultColorMap },
{ "LineQuality", "%d", 0, VIS_VISUAL_PARAM_INT, 1, 0.0, NULL },
{ "LineStyle", "%d", 0, VIS_VISUAL_PARAM_INT, line_style_line, 0.0, NULL },
{ NULL, NULL, 0, 0, 0,0.0, NULL }
};
int n = 0;
ArrowParams[n++].Offset = (char *)&arrow.VectorData[0] - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.VectorData[1] - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.VectorData[2] - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.VectorData[3] - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.ColorData - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.LengthData - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.ThresholdData - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.Style - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.Floor - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.Ceiling - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.RadiusScale - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.LengthScale - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.EqualLength - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.EqualRadius - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.Material - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.ColorMap - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.LineQuality - (char *)&arrow;
ArrowParams[n++].Offset = (char *)&arrow.LineStyle - (char *)&arrow;
VisualDef.VisualName = visual_name;
VisualDef.RealizeVisual = (int (*)()) vis_arrow;
VisualDef.AllocParams = (void *(*)()) vis_arrow_alloc;
VisualDef.DeleteParams = (void (*)()) vis_arrow_delete;
VisualDef.VisualParams = ArrowParams;
return vis_add_visual_type( &VisualDef );
}