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);
}
Пример #2
0
void _lucIsosurface_Write( void* drawingObject, lucDatabase* database, Bool walls )
{
   /* Export surface triangles */
   lucIsosurface* self = (lucIsosurface*)drawingObject;
   Index triangle_I;
   int i;
   for ( triangle_I = 0 ; triangle_I < self->triangleCount ; triangle_I++)
   {
      if (self->triangleList[triangle_I].wall != walls) continue;
      for (i=0; i<3; i++)
      {
         /* Dump vertex pos, [value] */
         float coordf[3] = {self->triangleList[triangle_I].pos[i][0],
                            self->triangleList[triangle_I].pos[i][1],
                            self->triangleList[triangle_I].pos[i][2]};
         float value = self->triangleList[triangle_I].value[i];
         lucDatabase_AddVertices(database, 1, lucTriangleType, coordf);
         if (self->colourField && self->colourMap)
            lucDatabase_AddValues(database, 1, lucTriangleType, lucColourValueData, self->colourMap, &value);
      }
   }
}
Пример #3
0
void _lucSwarmVectors_PlotParticle( void* drawingObject, lucDatabase* database, Particle_Index lParticle_I )
{
   lucSwarmVectors*        self                = (lucSwarmVectors*)drawingObject;
   SwarmVariable*          lengthVariable      = self->lengthVariable;
   SwarmVariable*          thicknessVariable   = self->thicknessVariable;
   float                   length;
   XYZ                     direction           = { 1, 0, 0 };

   SwarmVariable_ValueAt( self->directionVariable, lParticle_I, direction );

   length = lucSwarmViewer_GetScalar(lengthVariable, lParticle_I, self->length);

   //float max = self->directionVariable ? FieldVariable_GetMaxGlobalFieldMagnitude( self->directionVariable ) : 0;
   float vecf[3] = {direction[0]*length, direction[1]*length, direction[2]*length};
   lucDatabase_AddVectors(database, 1, lucVectorType, 0, 0, vecf);

   if (thicknessVariable)
   {
      float thickness = lucSwarmViewer_GetScalar(thicknessVariable, lParticle_I, self->thickness);
      lucDatabase_AddValues(database, 1, self->geomType, lucXWidthData, NULL, &thickness);
   }
}
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 lucContourCrossSection_PlotPoint(lucContourCrossSection* self, lucDatabase* database, char edge, double isovalue, int aIndex, int bIndex)
{
   Coord vertex;
   double aPos = (double)aIndex;
   double bPos = (double)bIndex;
   double leftBtm = self->values[aIndex][bIndex][0];
   double rightBtm = self->values[aIndex+1][bIndex][0];
   double leftTop = self->values[aIndex][bIndex+1][0];
   double rightTop = self->values[aIndex+1][bIndex+1][0];

   switch (edge)
   {
   case BOTTOM:
      aPos += (isovalue - leftBtm)/(rightBtm - leftBtm);
      break;
   case TOP:
      aPos += (isovalue - leftTop)/(rightTop - leftTop);
      bPos += 1.0;
      break;
   case LEFT:
      bPos += (isovalue - leftBtm)/(leftTop - leftBtm);
      break;
   case RIGHT:
      aPos += 1.0;
      bPos += (isovalue - rightBtm)/(rightTop - rightBtm);
      break;
   }

   lucCrossSection_Interpolate2d(self, aPos / (double)(self->resolutionA-1), bPos / (double)(self->resolutionB-1), vertex);

   /* Dump vertex pos */
   float pos[3] = {vertex[0], vertex[1], vertex[2]};
   float value = isovalue;
   lucDatabase_AddVertices(database, 1, lucLineType, pos);
   if (self->colourMap)
      lucDatabase_AddValues(database, 1, lucLineType, lucColourValueData, self->colourMap, &value);

   if (self->showValues && self->coordIndex % 4 == edge) 
   { 
      if (self->printedIndex < self->coordIndex && (0 == bIndex || 0 == aIndex || bIndex == (self->resolutionB-1) || aIndex == (self->resolutionA-1)))
      {
         char label[32];
         double dimCoeff = 1.0; /* coefficient for dimensionalising field */
         //TODO: Fix scaling/units
//         /* very hacky to get the scaling component */
//         Scaling* theScaling = NULL;
//         if (self->fieldVariable->context) theScaling = self->fieldVariable->context->scaling;
//         if (self->fieldVariable->o_units && theScaling)
//            dimCoeff = Scaling_ParseDimCoeff( theScaling, self->fieldVariable->o_units );
//
         /* Add the vertex for the label as a point */
         lucDatabase_AddVertices(database, 1, lucPointType, pos);
         /* Add to the label data */
         sprintf(label, " %g", isovalue * dimCoeff);
         //sprintf(label, " %g%s", isovalue * dimCoeff,
         //         self->printUnits && self->fieldVariable->o_units ? self->fieldVariable->o_units : "");
         lucDatabase_AddLabel(database, lucPointType, label);

         self->printedIndex = self->coordIndex;
      }
   }
}
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);
}