void lucContourCrossSection_DrawCrossSection( void* drawingObject, lucDatabase* database ) { lucContourCrossSection* self = (lucContourCrossSection*)drawingObject; double minIsovalue = self->minIsovalue; double maxIsovalue = self->maxIsovalue; double isovalue; /* Custom max, min, use global min/max if equal (defaults to both zero) */ if (self->minIsovalue == self->maxIsovalue) { //minIsovalue = FieldVariable_GetMinGlobalFieldMagnitude(self->fieldVariable); //maxIsovalue = FieldVariable_GetMaxGlobalFieldMagnitude(self->fieldVariable); } /* Sample the 2d cross-section */ lucCrossSection_SampleField(self, False); if (database->rank == 0) { /* Draw isovalues at interval */ if ( self->interval <= 0.0 ) return; for ( isovalue = minIsovalue ; isovalue <= maxIsovalue ; isovalue += self->interval ) { if ( self->colourMap ) lucColourMap_SetColourFromValue( self->colourMap, isovalue, self->opacity); lucContourCrossSection_DrawContour( self, database, isovalue); self->coordIndex++; } } /* Free memory */ lucCrossSection_FreeSampleData(self); }
void lucScalarFieldCrossSection_DrawCrossSection( void* drawingObject, lucDatabase* database, Bool backFacing) { lucScalarFieldCrossSection* self = (lucScalarFieldCrossSection*)drawingObject; /* Sample the 2d cross-section */ lucCrossSection_SampleField(self, backFacing); /* Calibrate Colour Map */ if (self->colourMap) lucColourMap_CalibrateFromFieldVariable(self->colourMap, self->fieldVariable); if (self->context->rank == 0) { int d; int count = self->resolutionA * self->resolutionB; lucDatabase_AddGridVertices(database, count, self->resolutionB, &self->vertices[0][0][0]); lucDatabase_AddValues(database, count, lucGridType, lucColourValueData, self->colourMap, &self->values[0][0][0]); /* Flip normal if back facing */ if (backFacing) for (d=0; d<3; d++) self->normal[d] = 0 - self->normal[d]; /* Add a single normal value */ lucDatabase_AddNormal(database, lucGridType, self->normal); } /* Free memory */ lucCrossSection_FreeSampleData(self); /* Start new geometry section - when used with multiple sections */ lucDatabase_OutputGeometry(database, self->id); }
void lucMeshSampler_DrawSlice(lucMeshSampler* self, lucDatabase* database) { /* Corners */ float corners[6] = {self->min[0], self->min[1], self->min[2], self->max[0], self->max[1], self->max[2]}; /* Sample the 2d cross-section */ lucMeshCrossSection_Sample(self, False); if (self->rank == 0 && database) { /* Write slice values on root processor */ lucDatabase_AddVolumeSlice(database, self->elementRes[I_AXIS]+1, self->elementRes[J_AXIS]+1, corners, self->colourMap, &self->values[0][0][0]); } lucCrossSection_FreeSampleData(self); /* Start new geometry section - when used with multiple sections */ lucDatabase_OutputGeometry(database, self->id); }
void _lucVectorArrowCrossSection_DrawCrossSection( void* drawingObject, lucDatabase* database, Dimension_Index dim ) { lucVectorArrowCrossSection* self = (lucVectorArrowCrossSection*)drawingObject; FieldVariable* vectorVariable = self->fieldVariable; double min = 0.0, max = self->maximum; Index aIndex, bIndex; Journal_Firewall( vectorVariable->fieldComponentCount == vectorVariable->dim, lucError, "Error - in %s(): provided FieldVariable \"%s\" has %u components - but %s Component " "can only visualse FieldVariables with %d components.\n", __func__, vectorVariable->name, vectorVariable->fieldComponentCount, self->type, vectorVariable->dim ); if ( True == self->dynamicRange ) { min = FieldVariable_GetMinGlobalFieldMagnitude( vectorVariable ); max = FieldVariable_GetMaxGlobalFieldMagnitude( vectorVariable ); } /* Force 3d vectors */ lucCrossSection_AllocateSampleData(self, 3); /* Sample the 2d cross-section */ lucCrossSection_SampleField(self, False); /* Write only values that have data on this processor! */ for ( aIndex = 0 ; aIndex < self->resolutionA ; aIndex++ ) { for ( bIndex = 0 ; bIndex < self->resolutionB ; bIndex++ ) { if (self->values[aIndex][bIndex][0] != HUGE_VAL) { lucDatabase_AddVertices(database, 1, lucVectorType, &self->vertices[aIndex][bIndex][0]); lucDatabase_AddVectors(database, 1, lucVectorType, min, max, &self->values[aIndex][bIndex][0]); } } } lucCrossSection_FreeSampleData(self); }
void _lucIsosurfaceCrossSection_Draw( void* drawingObject, lucDatabase* database, void* _context ) { lucIsosurfaceCrossSection* self = (lucIsosurfaceCrossSection*)drawingObject; lucIsosurface* isosurf = self->isosurface; double minIsovalue = self->minIsovalue; double maxIsovalue = self->maxIsovalue; lucColourMap* colourMap = self->colourMap; int i, j, k; double isovalue; Index triangle_I; /* Custom max, min, use global min/max if equal (defaults to both zero) */ if (minIsovalue == maxIsovalue) { //minIsovalue = FieldVariable_GetMinGlobalFieldMagnitude(self->fieldVariable); //maxIsovalue = FieldVariable_GetMaxGlobalFieldMagnitude(self->fieldVariable); } if (colourMap) lucColourMap_SetMinMax(colourMap, minIsovalue, maxIsovalue); /* Copy object id */ isosurf->id = self->id; if (self->rank == 0) { /* Calculate a value we can use to offset each surface section slightly * so they appear in the same position but don't actually overlap */ Coord min, max; float shift = 0; float range = 0; int d; Mesh_GetGlobalCoordRange(self->mesh, min, max ); for (d=0; d<3; d++) range += (max[d] - min[d]) / 5000.0; range /= 3.0; /* Allocate Memory */ Vertex** points = Memory_Alloc_2DArray( Vertex , 8, 1, "array for marching squares"); /* Draw isovalues at each interval from min to max */ for ( isovalue = minIsovalue ; isovalue <= maxIsovalue ; isovalue += self->interval ) { float nshift[3] = {shift * self->normal[0], shift * self->normal[1], shift * self->normal[2]}; shift += range; isosurf->triangleCount = 0; /* Reset */ isosurf->colourMap = NULL; if ( colourMap ) lucColourMap_GetColourFromValue(colourMap, isovalue, &isosurf->colour, self->opacity); /* Run marching rectangles for this isovalue */ isosurf->isovalue = isovalue; for ( i = 0 ; i < self->resolutionA-1 ; i++ ) { for ( j = 0 ; j < self->resolutionB-1 ; j++ ) { /* Copy vertex */ for (k = 0; k<3; k++) { points[LEFT_BOTTOM]->pos[k] = self->vertices[i][j][k] + nshift[k]; points[RIGHT_BOTTOM]->pos[k] = self->vertices[i+1][j][k] + nshift[k]; points[LEFT_TOP]->pos[k] = self->vertices[i][j+1][k] + nshift[k]; points[RIGHT_TOP]->pos[k] = self->vertices[i+1][j+1][k] + nshift[k]; } /* Copy value */ points[LEFT_BOTTOM]->value = self->values[i][j][0]; points[RIGHT_BOTTOM]->value = self->values[i+1][j][0]; points[LEFT_TOP]->value = self->values[i][j+1][0]; points[RIGHT_TOP]->value = self->values[i+1][j+1][0]; /* Interpolate mid-points and create triangles */ lucIsosurface_WallElement( isosurf, points ); } } /* Draw the surface section */ isosurf->colourMap = self->colourMap; _lucIsosurface_Draw(self->isosurface, database, _context ); /* Export colour values */ if (self->colourMap) { float iso = isovalue; for ( triangle_I = 0 ; triangle_I < isosurf->triangleCount ; triangle_I++) for (i=0; i<3; i++) lucDatabase_AddValues(database, 1, lucTriangleType, lucColourValueData, self->colourMap, &iso); } } Memory_Free( points ); } /* Free memory */ lucCrossSection_FreeSampleData(self); }
void _lucEigenvectorsCrossSection_DrawCrossSection( void* drawingObject, lucDatabase* database, Dimension_Index dim ) { lucEigenvectorsCrossSection* self = (lucEigenvectorsCrossSection*)drawingObject; FieldVariable* tensorField = self->fieldVariable; SymmetricTensor tensor; Eigenvector eigenvectorList[3]; Dimension_Index dim_I; Index aIndex, bIndex; /* Sample the 2d cross-section */ lucCrossSection_SampleField(self, False); for ( aIndex = 0 ; aIndex < self->resolutionA ; aIndex++ ) { for ( bIndex = 0 ; bIndex < self->resolutionB ; bIndex++ ) { if (self->values[aIndex][bIndex][0] != HUGE_VAL) { /* Get tensor data & position */ int t; for (t=0; t<tensorField->fieldComponentCount; t++) tensor[t] = self->values[aIndex][bIndex][t]; SymmetricTensor_CalcAllEigenvectors( tensor, dim, eigenvectorList ); float pos[3] = {self->vertices[aIndex][bIndex][0], self->vertices[aIndex][bIndex][1], self->vertices[aIndex][bIndex][2]}; if (self->plotEigenVector) { for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) { float vec[3] = {eigenvectorList[ dim_I ].vector[0], eigenvectorList[ dim_I ].vector[1], eigenvectorList[ dim_I ].vector[2]}; lucDatabase_AddVertices(database, 1, lucVectorType, pos); lucDatabase_AddRGBA(database, lucVectorType, self->opacity, &self->colours[ dim_I ]); if (self->useEigenValue) { vec[0] *= eigenvectorList[ dim_I ].eigenvalue; vec[1] *= eigenvectorList[ dim_I ].eigenvalue; if (dim > 2) vec[2] *= eigenvectorList[ dim_I ].eigenvalue; else vec[2] = 0; } lucDatabase_AddVectors(database, 1, lucVectorType, 0, 1, vec); } } if (self->plotEigenValue) { float pointSize = 0; for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) { lucDatabase_AddVertices(database, 1, lucShapeType, pos); /* The EigenValue can be negative.... Got to attribute a potential */ /* colour for negative values, one for each dim as well */ if ( eigenvectorList[ dim_I ].eigenvalue >= 0) { pointSize = eigenvectorList[ dim_I ].eigenvalue; lucDatabase_AddRGBA(database, lucShapeType, self->opacity, &self->colours[ dim_I ]); } else { pointSize = -eigenvectorList[ dim_I ].eigenvalue; lucDatabase_AddRGBA(database, lucShapeType, self->opacity, &self->colourForNegative[ dim_I ]); } lucDatabase_AddValues(database, 1, lucShapeType, lucXWidthData, NULL, &pointSize); } } } } } lucCrossSection_FreeSampleData(self); }