cgma
Cholla.h File Reference
#include "CubitDefines.h"

Go to the source code of this file.

Defines

#define NUM_EDGE_CPTS   3
#define NUM_TRI_CPTS   6
#define NUM_QUAD_CPTS   15

Functions

void constructBezier (double angle, int numTri, int numQuad, int numEdge, int numVert, int *triEdge, int *quadEdge, int *edgeVert, double *vert, double *edgeCtrlPts, double *triCtrlPts, double *quadCtrlPts)
void constructTriNormals (double angle, int numTri, int numEdge, int numVert, int *triEdge, int *edgeVert, double *vert, double *triVertNorms, double *edgeVertTang, int *edgeTypeFlags)
void constructQuadNormals (double angle, int numQuad, int numEdge, int numVert, int *quadEdge, int *edgeVert, double *vert, double *quadVertNorms, double *edgeVertTang, int *edgeTypeFlags)
CubitStatus constructTriNormalsFromFile (const char *filename, int numTri, int numEdge, int *triEdge, int *edgeVert, double *triVertNorms, double *edgeVertTang)
CubitStatus constructQuadNormalsFromFile (const char *filename, int numQuad, int numEdge, int *quadEdge, int *edgeVert, double *quadVertNorms, double *edgeVertTang)
CubitStatus readMBGNormalFile (const char *filename, int *numTri, int *numQuad, int *numEdge, int **edgeVert, double **edgeVertTang, int **triVert, double **triVertNorms, int **quadVert, double **quadVertNorms)
void evalBezierFace (int numFace, int numEdge, int numVert, int numVertPerFace, int *faceEdge, int *edgeVert, double *vert, double *faceCtrlPts, double *edgeCtrlPts, int numLocs, double *paramLocation, double *location, double *normal, double *deriv)
void evalBezierFaceFromNorms (int numFace, int numEdge, int numVert, int numVertPerFace, int *faceEdge, int *edgeVert, double *vert, double *vertNorms, double *edgeVertTang, int numLocs, double *paramLocation, double *location, double *normal, double *deriv)
void projToBezierFace (int numFace, int numEdge, int numVert, int numVertPerFace, int *faceEdge, int *edgeVert, double *vert, double *faceCtrlPts, double *edgeCtrlPts, int numLocs, double *xyz, int specify_tol, double converge_tol, double *xyzOnFace, double *normal, double *deriv)
void projToBezierFaceFromNorms (int numFace, int numEdge, int numVert, int numVertPerFace, int *faceEdge, int *edgeVert, double *vert, double *vertNorms, double *edgeVertTang, int numLocs, double *xyz, int specify_tol, double converge_tol, double *xyzOnFace, double *normal, double *deriv)
void evalBezierEdgeFromTans (int numEdge, int numVert, int *edgeVert, double *vert, double *edgeVertTang, int numLocs, double *paramLocation, double *location, double *tangent)
void evalBezierEdge (int numEdge, int numVert, int *edgeVert, double *vert, double *edgeCtrlPts, int numLocs, double *paramLocation, double *location, double *tangent)
void projToBezierEdgeFromTans (int numEdge, int numVert, int *edgeVert, double *vert, double *edgeVertTang, int numLocs, double *xyz, double *xyzOnEdge, double *tangent)
void projToBezierEdge (int numEdge, int numVert, int *edgeVert, double *vert, double *edgeCtrlPts, int numLocs, double *xyz, double *xyzOnEdge, double *tangent, double *t_value)
void dumpMesh (const char *fileName, int includeResults, double angle, int numTri, int numQuad, int numEdge, int numVert, int *triEdge, int *quadEdge, int *edgeVert, double *vert, double *edgeCtrlPts, double *triCtrlPts, double *quadCtrlPts)
void dumpResults (const char *fileName, int numEdge, int numTri, int numQuad, double *edgeCtrlPts, double *triCtrlPts, double *quadCtrlPts)
void importMesh (const char *fileName, int *resultsIncluded, double *angle, int *numTri, int *numQuad, int *numEdge, int *numVert, int **triEdge, int **quadEdge, int **edgeVert, double **vert, double **edgeCtrlPts, double **triCtrlPts, double **quadCtrlPts)
void importResults (const char *fileName, int *numEdge, int *numTri, int *numQuad, double **edgeCtrlPts, double **triCtrlPts, double **quadCtrlPts)

Detailed Description

  • Class: Cholla
  • Description: C-style Interface for the Cholla module
  • Facet-based geometry definition and evaluation
  • Owner: Steven J. Owen
  • Checked by:
  • Version:

Definition in file Cholla.h.


Define Documentation

#define NUM_EDGE_CPTS   3

Definition at line 14 of file Cholla.h.

#define NUM_QUAD_CPTS   15

Definition at line 16 of file Cholla.h.

#define NUM_TRI_CPTS   6

Definition at line 15 of file Cholla.h.


Function Documentation

void constructBezier ( double  angle,
int  numTri,
int  numQuad,
int  numEdge,
int  numVert,
int *  triEdge,
int *  quadEdge,
int *  edgeVert,
double *  vert,
double *  edgeCtrlPts,
double *  triCtrlPts,
double *  quadCtrlPts 
)

Return control points for a quartic Bezier for each face, using a given feature angle tolerance to distinguish C0 and C1 edges. Separate arrays of tris and quad faces should be supplied

Parameters:
angle- (IN) feature angle tolerance (degrees)
numTri- (IN) number of quad faces
numQuad- (IN) number of triangle faces
numEdge- (IN) number of edges
numVert- (IN) number of vertices
triEdge- (IN) array of face to edge numbering, length 3 * numTri
quadEdge- (IN) array of face to edge numbering, length 4 * numQuad
edgeVert- (IN) array of edge to vertex numbering, length 2*numEdge
vert- (IN) array of vertex coordinates, length 3*numVert
edgeCtrlPts- (OUT) array of control points computed at the edges length 3*(3*numEdge)
triCtrlPts- (OUT) array of control points computed at the triangles length 3*(6*numTri)
quadCtrlPts- (OUT) array of control points computed at the quads length 3*(15*numQuad)

Definition at line 84 of file Cholla.cpp.

{

  // create arrays of facet entities from the arrays

  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  if (numTri > 0)
    facet_array = new CubitFacet * [numTri];
  CubitQuadFacet **qfacet_array = NULL;
  if (numQuad > 0)
    qfacet_array = new CubitQuadFacet * [numQuad];
  DLIList<FacetEntity *> facet_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // create lists of points and edges

  int ii;
  DLIList<CubitPoint *> point_list;
  for (ii=0; ii<numVert; ii++)  
    point_list.append(point_array[ii]);  

  DLIList<CubitFacetEdge *> edge_list;
  for (ii=0; ii<numEdge; ii++)
    edge_list.append(edge_array[ii]);

  // prepare the ChollaEngine

  DLIList<FacetEntity *> fpoint_list, fedge_list;
  CAST_LIST_TO_PARENT( point_list, fpoint_list );
  CAST_LIST_TO_PARENT( edge_list,  fedge_list );
  ChollaEngine *ceng = new ChollaEngine( facet_list, fedge_list, fpoint_list );

  CubitBoolean use_feature_angle;
  if (angle < 0.00001 || angle > 179.9999)
    use_feature_angle = CUBIT_FALSE;
  else
    use_feature_angle = CUBIT_TRUE;
  int interp_order = 4;  // assume we are creating beziers
  CubitBoolean smooth_non_manifold = CUBIT_TRUE;
  CubitBoolean split_surfaces = CUBIT_FALSE;

  // create the geometry
    
  //CubitStatus rv = 
  ceng->create_geometry(use_feature_angle,angle,
                        interp_order,smooth_non_manifold,
                        split_surfaces);

  // get the control points on edges

  int jj;
  int index;
  CubitVector *control_points;
  CubitFacetEdge *edge_ptr;
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    control_points = edge_ptr->control_points();
    assert(control_points != NULL);
    for (jj=0; jj<NUM_EDGE_CPTS; jj++)
    {
      index = 3 * (ii * NUM_EDGE_CPTS + jj); 
      edgeCtrlPts[index] = control_points[jj].x();
      edgeCtrlPts[index+1] = control_points[jj].y();
      edgeCtrlPts[index+2] = control_points[jj].z();
    }
  }

  // get the control points on triangles

  CubitFacet *facet_ptr;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    control_points = facet_ptr->control_points();
    assert(control_points != NULL);
    for (jj=0; jj<NUM_TRI_CPTS; jj++)
    {
      index = 3 * (ii * NUM_TRI_CPTS + jj); 
      triCtrlPts[index] = control_points[jj].x();
      triCtrlPts[index+1] = control_points[jj].y();
      triCtrlPts[index+2] = control_points[jj].z();
    }
  }

    // get the control points on quads

  //CubitVector qctrl_points[NUM_QUAD_CPTS];
  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    index = 3 * (ii * NUM_QUAD_CPTS);
    qfacet_ptr->get_control_points( &(quadCtrlPts[index]) );
  }

  // delete the ChollaEngine

  ceng->delete_eval_tools();
  ceng->delete_me();
  delete ceng;

  // delete temp arrays (facets are deleted with the eval tool)

  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_array[ii]->remove_tri_facets();
    delete qfacet_array[ii];
  }
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 

}
void constructQuadNormals ( double  angle,
int  numQuad,
int  numEdge,
int  numVert,
int *  quadEdge,
int *  edgeVert,
double *  vert,
double *  quadVertNorms,
double *  edgeVertTang,
int *  edgeTypeFlags 
)

Return normal and tangents for on a list of quad faces a given feature angle tolerance to distinguish C0 and C1 edges. Separate arrays of tris and quad faces should be supplied

Parameters:
angle- (IN) feature angle tolerance (degrees)
numQuad- (IN) number of quad faces
numEdge- (IN) number of edges
numVert- (IN) number of vertices
quadEdge- (IN) array of face to edge numbering, length 4 * numQuad
edgeVert- (IN) array of edge to vertex numbering, length 2*numEdge
vert- (IN) array of vertex coordinates, length 3*numVert
quadVertNorms- (OUT) array of normals at the quad vertices length 3*(4*numQuad)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)
edgeTypeFlags- (OUT) array of flags labeling the type of each edge, length numEdge
2 = non-manifold edge
1 = concave feature edge
0 = non-feature edge
-1= convex feature edge

Definition at line 366 of file Cholla.cpp.

{

  // create arrays of facet entities from the arrays

  int *triEdge = NULL;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  CubitQuadFacet **qfacet_array = NULL; 
  int numTri = 0;
  if (numQuad > 0)
    qfacet_array = new CubitQuadFacet * [numQuad];
  DLIList<FacetEntity *> facet_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }
  // create lists of points and edges

  int ii;
  
  DLIList<CubitPoint *> point_list;
  for (ii=0; ii<numVert; ii++)  
    point_list.append(point_array[ii]);  

  DLIList<CubitFacetEdge *> edge_list;
  for (ii=0; ii<numEdge; ii++)
    edge_list.append(edge_array[ii]);

  // prepare the ChollaEngine

  DLIList<FacetEntity *> fpoint_list, fedge_list;
  CAST_LIST_TO_PARENT( point_list, fpoint_list );
  CAST_LIST_TO_PARENT( edge_list,  fedge_list );
  ChollaEngine *ceng = new ChollaEngine( facet_list, fedge_list, fpoint_list );

  CubitBoolean use_feature_angle;
  if (angle < 0.00001 || angle > 179.9999)
    use_feature_angle = CUBIT_FALSE;
  else
    use_feature_angle = CUBIT_TRUE;
  int interp_order = 4;  // assume we are creating beziers
  CubitBoolean smooth_non_manifold = CUBIT_TRUE;
  CubitBoolean split_surfaces = CUBIT_FALSE;

  // create the geometry
 
  ceng->create_geometry(use_feature_angle,angle,
                        interp_order,smooth_non_manifold,
                        split_surfaces);

  // get the control points on edges and infer the tangents

  int mydebug = 0;
  FILE *fp = NULL;
  if (mydebug)
  {
    fp = fopen("edges.txt", "w");
  }
  int index = 0;
  CubitVector *control_points;
  CubitFacetEdge *edge_ptr;
  CubitVector v0, v1, t0, t1;
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    v0 = edge_ptr->point(0)->coordinates();
    v1 = edge_ptr->point(1)->coordinates();
    control_points = edge_ptr->control_points();
    assert(control_points != NULL);
    if (mydebug)
    {
      int kk;
      for(kk=0; kk<3; kk++);
      fprintf(fp, "(%d) %.6f %.6f %.6f\n", edge_ptr->id(), v0.x(), v0.y(), v0.z());
      fprintf(fp, "    %.6f %.6f %.6f\n", control_points[0].x(), control_points[0].y(), control_points[0].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", control_points[1].x(), control_points[1].y(), control_points[1].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", control_points[2].x(), control_points[2].y(), control_points[2].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", v1.x(), v1.y(), v1.z());
    }
    index = 6 * ii; 
    t0 = control_points[0] - v0;
    t1 = v1 - control_points[2];
    if(edge_ptr->is_flipped()){
      t0 *= (-1.0);
      t1 *= (-1.0);
    }
    t0.normalize();
    t1.normalize();
    edgeVertTang[index  ] = t0.x();
    edgeVertTang[index+1] = t0.y();
    edgeVertTang[index+2] = t0.z();
    edgeVertTang[index+3] = t1.x();
    edgeVertTang[index+4] = t1.y();
    edgeVertTang[index+5] = t1.z();
    edgeTypeFlags[ii]=classify_local_convexity_at_edge(edge_ptr);
  }
  if (mydebug)
  {
    fclose(fp);
  }

  // get the normal on quad

  CubitVector n0, n1, n2, n3;
  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    index = 12 * ii;
    n0 = qfacet_ptr->point(0)->normal(qfacet_ptr);
    n1 = qfacet_ptr->point(1)->normal(qfacet_ptr);
    n2 = qfacet_ptr->point(2)->normal(qfacet_ptr);
    n3 = qfacet_ptr->point(3)->normal(qfacet_ptr);
    quadVertNorms[index     ] = n0.x();
    quadVertNorms[index + 1 ] = n0.y();
    quadVertNorms[index + 2 ] = n0.z();
    quadVertNorms[index + 3 ] = n1.x();
    quadVertNorms[index + 4 ] = n1.y();
    quadVertNorms[index + 5 ] = n1.z();
    quadVertNorms[index + 6 ] = n2.x();
    quadVertNorms[index + 7 ] = n2.y();
    quadVertNorms[index + 8 ] = n2.z();
    quadVertNorms[index + 9 ] = n3.x();
    quadVertNorms[index + 10] = n3.y();
    quadVertNorms[index + 11] = n3.z();
  }
  
  // delete the ChollaEngine

  ceng->delete_eval_tools();
  ceng->delete_me();
  delete ceng;

  // delete temp arrays

  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_array[ii]->remove_tri_facets();
    delete qfacet_array[ii];
  }
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
CubitStatus constructQuadNormalsFromFile ( const char *  filename,
int  numQuad,
int  numEdge,
int *  quadEdge,
int *  edgeVert,
double *  quadVertNorms,
double *  edgeVertTang 
)

Return normal and tangents for on a list of quad faces a given a file containing the geometric normals and tangents. Separate arrays of tris and quad faces should be supplied

Parameters:
filename- (IN) full path and name of the text file containing the geometric surface normals and tangents. This file is output from Cubit when exporting an exodus file.
numQuad- (IN) number of quad faces
numEdge- (IN) number of edges
quadEdge- (IN) array of face to edge numbering, length 4 * numQuad
edgeVert- (IN) array of edge to vertex numbering, length 2*numEdge
quadVertNorms- (OUT) array of normals at the quad vertices length 3*(4*numQuad)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)

Definition at line 2512 of file Cholla.cpp.

{
    CubitStatus status = CUBIT_SUCCESS;
    int num_file_quads = 0,
        num_file_edges = 0,
        *edge_nodes_file = NULL,
        *quad_nodes_file = NULL;
    double *edge_node_tangs_file = NULL,
           *quad_node_norms_file = NULL;

    status = readMBGNormalFile( filename,
                                NULL,
                                &num_file_quads,
                                &num_file_edges,
                                &edge_nodes_file,
                                &edge_node_tangs_file,
                                NULL,
                                NULL,
                                &quad_nodes_file,
                                &quad_node_norms_file );

    if ( status == CUBIT_SUCCESS && numEdge > 0 )
    {
        status = extractEdgeTangsFromFile( num_file_edges,
                                           edge_nodes_file,
                                           edge_node_tangs_file,
                                           numEdge,
                                           edgeVert,
                                           edgeVertTang );
    }
    if ( status == CUBIT_SUCCESS && numQuad > 0 )
    {
        status = extractQuadNormalsFromFile( num_file_quads,
                                             quad_nodes_file,
                                             quad_node_norms_file,
                                             numQuad,
                                             edgeVert,
                                             quadEdge,
                                             quadVertNorms );
    }

    delete [] edge_nodes_file;
    delete [] quad_nodes_file;
    delete [] edge_node_tangs_file;
    delete [] quad_node_norms_file;
    return status;
}
void constructTriNormals ( double  angle,
int  numTri,
int  numEdge,
int  numVert,
int *  triEdge,
int *  edgeVert,
double *  vert,
double *  triVertNorms,
double *  edgeVertTang,
int *  edgeTypeFlags 
)

Return normal and tangents for on a list of triangles a given feature angle tolerance to distinguish C0 and C1 edges. Separate arrays of tris and quad faces should be supplied

Parameters:
angle- (IN) feature angle tolerance (degrees)
numTri- (IN) number of tri faces
numEdge- (IN) number of edges
numVert- (IN) number of vertices
triEdge- (IN) array of face to edge numbering, length 3 * numTri
edgeVert- (IN) array of edge to vertex numbering, length 2*numEdge
vert- (IN) array of vertex coordinates, length 3*numVert
triVertNorms- (OUT) array of normals at the triangle vertices length 3*(3*numTri)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)
edgeTypeFlags- (OUT) array of flags labeling the type of each edge, length numEdge
2 = non-manifold edge
1 = concave feature edge
0 = non-feature edge
-1= convex feature edge

Definition at line 222 of file Cholla.cpp.

{

  // create arrays of facet entities from the arrays

  int* quadEdge = NULL;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  if (numTri > 0)
    facet_array = new CubitFacet * [numTri];
  int numQuad = 0;
  CubitQuadFacet **qfacet_array = NULL;
  DLIList<FacetEntity *> facet_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // create lists of points and edges

  int ii;
  DLIList<CubitPoint *> point_list;
  for (ii=0; ii<numVert; ii++)  
    point_list.append(point_array[ii]);  

  DLIList<CubitFacetEdge *> edge_list;
  for (ii=0; ii<numEdge; ii++){
    edge_list.append(edge_array[ii]);
  }
  

  // prepare the ChollaEngine

  DLIList<FacetEntity *> fpoint_list, fedge_list;
  CAST_LIST_TO_PARENT( point_list, fpoint_list );
  CAST_LIST_TO_PARENT( edge_list,  fedge_list );
  ChollaEngine *ceng = new ChollaEngine( facet_list, fedge_list, fpoint_list );

  CubitBoolean use_feature_angle;
  if (angle < 0.00001 || angle > 179.9999)
    use_feature_angle = CUBIT_FALSE;
  else
    use_feature_angle = CUBIT_TRUE;
  int interp_order = 4;  // assume we are creating beziers
  CubitBoolean smooth_non_manifold = CUBIT_TRUE;
  CubitBoolean split_surfaces = CUBIT_FALSE;

  // create the geometry
    
  //CubitStatus rv = 
  ceng->create_geometry(use_feature_angle,angle,
                        interp_order,smooth_non_manifold,
                        split_surfaces);

  // get the control points on edges and infer the tangents

  int index = 0;
  CubitVector *control_points;
  CubitFacetEdge *edge_ptr;
  CubitVector v0, v1, t0, t1;
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    v0 = edge_ptr->point(0)->coordinates();
    v1 = edge_ptr->point(1)->coordinates();
    control_points = edge_ptr->control_points();
    assert(control_points != NULL);
    index = 6 * ii;
    t0 = control_points[0] - v0;
    t1 = v1 - control_points[2];
    if(edge_ptr->is_flipped()){
      t0 *= (-1.0);
      t1 *= (-1.0);
    }
    t0.normalize();
    t1.normalize();
    edgeVertTang[index  ] = t0.x();
    edgeVertTang[index+1] = t0.y();
    edgeVertTang[index+2] = t0.z();
    edgeVertTang[index+3] = t1.x();
    edgeVertTang[index+4] = t1.y();
    edgeVertTang[index+5] = t1.z();
    edgeTypeFlags[ii]=classify_local_convexity_at_edge(edge_ptr);
  }

  // get the normal on triangles

  CubitVector n0, n1, n2;
  CubitFacet *facet_ptr;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    index = 9 * ii;
    n0 = facet_ptr->point(0)->normal(facet_ptr);
    n1 = facet_ptr->point(1)->normal(facet_ptr);
    n2 = facet_ptr->point(2)->normal(facet_ptr);
    triVertNorms[index    ] = n0.x();
    triVertNorms[index + 1] = n0.y();
    triVertNorms[index + 2] = n0.z();
    triVertNorms[index + 3] = n1.x();
    triVertNorms[index + 4] = n1.y();
    triVertNorms[index + 5] = n1.z();
    triVertNorms[index + 6] = n2.x();
    triVertNorms[index + 7] = n2.y();
    triVertNorms[index + 8] = n2.z();
  }

  // delete the ChollaEngine

  ceng->delete_eval_tools();
  ceng->delete_me();
  delete ceng;

  // delete temp arrays (facets are deleted with the eval tool)

  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_array[ii]->remove_tri_facets();
    delete qfacet_array[ii];
  }
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
CubitStatus constructTriNormalsFromFile ( const char *  filename,
int  numTri,
int  numEdge,
int *  triEdge,
int *  edgeVert,
double *  triVertNorms,
double *  edgeVertTang 
)

Return normal and tangents for on a list of triangles a given a file containing the geometric normals and tangents. Separate arrays of tris and quad faces should be supplied

Parameters:
filename- (IN) full path and name of the text file containing the geometric surface normals and tangents. This file is output from Cubit when exporting an exodus file.
numTri- (IN) number of tri faces
triVert- (IN) array of face to vertex numbering, length 3 * numTri
triVertNorms- (OUT) array of normals at the triangle vertices length 3*(3*numTri)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)

Definition at line 2578 of file Cholla.cpp.

{
    CubitStatus status = CUBIT_SUCCESS;
    int num_file_tris = 0,
        num_file_edges = 0,
        *edge_nodes_file = NULL,
        *tri_nodes_file = NULL;
    double *edge_node_tangs_file = NULL,
           *tri_node_norms_file = NULL;

    status = readMBGNormalFile( filename,
                                &num_file_tris,
                                NULL,
                                &num_file_edges,
                                &edge_nodes_file,
                                &edge_node_tangs_file,
                                &tri_nodes_file,
                                &tri_node_norms_file,
                                NULL,
                                NULL );

    if ( status == CUBIT_SUCCESS && numEdge > 0 )
    {
        status = extractEdgeTangsFromFile( num_file_edges,
                                           edge_nodes_file,
                                           edge_node_tangs_file,
                                           numEdge,
                                           edgeVert,
                                           edgeVertTang );
    }
    if ( status == CUBIT_SUCCESS && numTri > 0 )
    {
        status = extractTriNormalsFromFile( num_file_tris,
                                            tri_nodes_file,
                                            tri_node_norms_file,
                                            numTri,
                                            edgeVert,
                                            triEdge,
                                            triVertNorms );
    }

    delete [] edge_nodes_file;
    delete [] tri_nodes_file;
    delete [] edge_node_tangs_file;
    delete [] tri_node_norms_file;
    return status;
}
void dumpMesh ( const char *  fileName,
int  includeResults,
double  angle,
int  numTri,
int  numQuad,
int  numEdge,
int  numVert,
int *  triEdge,
int *  quadEdge,
int *  edgeVert,
double *  vert,
double *  edgeCtrlPts,
double *  triCtrlPts,
double *  quadCtrlPts 
)

Functions for debugging

Definition at line 1412 of file Cholla.cpp.

{
  FILE *fp = fopen(fileName, "w");
  assert(fp != NULL); // couldn't open file for writing
  
  // write the header info

  fprintf(fp, "Cholla version 1.0\n");
  time_stamp( fp );
  fprintf(fp, "%d %d %d %d %d\n", numTri, numQuad, numEdge, numVert, includeResults);
  fprintf(fp, "%f\n", angle);
  
  // faceEdgeBegin

  int ii;

  // faceEdge

  fprintf(fp, "triEdge\n");
  for(ii=0; ii<numTri; ii++)
  {
    fprintf(fp, "%d %d %d\n", triEdge[ii*3], triEdge[ii*3+1], triEdge[ii*3+2]);
  }

  fprintf(fp, "quadEdge\n");
  for(ii=0; ii<numQuad; ii++)
  {
    fprintf(fp, "%d %d %d %d\n", quadEdge[ii*4], quadEdge[ii*4+1],
                                 quadEdge[ii*4+2], quadEdge[ii*4+3]);
  }

  // edgeVert

  fprintf(fp, "edgeVert\n");
  for (ii=0; ii<numEdge; ii++)
  {
    fprintf(fp, "%d %d\n", edgeVert[ii*2], edgeVert[ii*2+1]);
  }

  // vert

  fprintf(fp, "vert\n");
  for (ii=0; ii<numVert; ii++)
  {
    fprintf(fp, "%f %f %f\n", vert[ii*3], vert[ii*3+1], vert[ii*3+2]);
  }

  if (includeResults != 0)
  {
     // edge control points

    int jj;
    fprintf(fp, "edgeCtrlPts\n");
    for(ii=0; ii<numEdge; ii++)
    {
      for (jj=0; jj<NUM_EDGE_CPTS; jj++)
      {
        fprintf(fp, "%f %f %f\n", edgeCtrlPts[ii*jj*3], 
                                     edgeCtrlPts[ii*jj*3+1], 
                                     edgeCtrlPts[ii*jj*3+2]);
      }
    }

    // triangle control points

    fprintf(fp, "triCtrlPts\n");
    for(ii=0; ii<numTri; ii++)
    {
      for (jj=0; jj<NUM_TRI_CPTS; jj++)
      {
        fprintf(fp, "%f %f %f\n", triCtrlPts[ii*jj*3], 
                                     triCtrlPts[ii*jj*3+1], 
                                     triCtrlPts[ii*jj*3+2]);
      }
    }

    // quad control points

    fprintf(fp, "quadCtrlPts\n");
    for(ii=0; ii<numQuad; ii++)
    {
      for (jj=0; jj<NUM_QUAD_CPTS; jj++)
      {
        fprintf(fp, "%f %f %f\n", quadCtrlPts[ii*jj*3], 
                                     quadCtrlPts[ii*jj*3+1], 
                                     quadCtrlPts[ii*jj*3+2]);
      }
    }
  }
  fclose(fp);
}
void dumpResults ( const char *  fileName,
int  numEdge,
int  numTri,
int  numQuad,
double *  edgeCtrlPts,
double *  triCtrlPts,
double *  quadCtrlPts 
)

Definition at line 1515 of file Cholla.cpp.

{
  FILE *fp = fopen( fileName, "w" );
  assert(fp != NULL);

    // write the header info

  fprintf(fp, "Cholla version 1.0 Results\n");
  time_stamp( fp );
  fprintf(fp, "%d %d %d\n", numEdge, numTri, numQuad );

  int ii,jj;
  fprintf(fp, "edgeCtrlPts\n");
  for(ii=0; ii<numEdge; ii++)
  {
    for (jj=0; jj<NUM_EDGE_CPTS; jj++)
    {
      fprintf(fp, "%f %f %f\n", edgeCtrlPts[ii*jj*3], 
                                   edgeCtrlPts[ii*jj*3+1], 
                                   edgeCtrlPts[ii*jj*3+2]);
    }
  }

  // triangle control points

  fprintf(fp, "triCtrlPts\n");
  for(ii=0; ii<numTri; ii++)
  {
    for (jj=0; jj<NUM_TRI_CPTS; jj++)
    {
      fprintf(fp, "%f %f %f\n", triCtrlPts[ii*jj*3], 
                                   triCtrlPts[ii*jj*3+1], 
                                   triCtrlPts[ii*jj*3+2]);
    }
  }

  // quad control points

  fprintf(fp, "quadCtrlPts\n");
  for(ii=0; ii<numQuad; ii++)
  {
    for (jj=0; jj<NUM_QUAD_CPTS; jj++)
    {
      fprintf(fp, "%f %f %f\n", quadCtrlPts[ii*jj*3], 
                                   quadCtrlPts[ii*jj*3+1], 
                                   quadCtrlPts[ii*jj*3+2]);
    }
  }

  fclose(fp);
}
void evalBezierEdge ( int  numEdge,
int  numVert,
int *  edgeVert,
double *  vert,
double *  edgeCtrlPts,
int  numLocs,
double *  paramLocation,
double *  location,
double *  tangent 
)

Evaluate a quartic Bezier curve at a specified parametric location given its control points. Evaluates location, and/or tangent.

Parameters:
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations length 3 * numVert
edgeCtrlPts- (IN) array of control pt locations for each edge in the bezier. The beziers are quartic, so there are 3 control pts per curve in addition to the 2 end pts for each curve for a total of 5 pts per edge. length = 3 * ( 3 * numEdge )
numLocs- (IN) number of locations to evaluate per edge
paramLocation- (IN) parametric location to evaluate on each edge length = numLocs
location- (OUT) evaluated point on edge at paramLocation length = numEdge * 3 * numLocs
tangent- (IN/OUT) evaluated tangent at parmLocation. If NULL then will not be evaluated. Return vector is normalized length = numEdge * 3 * numLocs

Definition at line 1945 of file Cholla.cpp.

{
CubitPoint **point_array = new CubitPoint * [numVert];
CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
CubitFacet **facet_array = NULL;
CubitQuadFacet **qfacet_array = NULL;
DLIList<FacetEntity *> facet_list;
int ii, index, numTri, numQuad;
int *triEdge, *quadEdge;
  triEdge = quadEdge = NULL;
  numTri = numQuad = 0;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  CubitFacetEdge *edge_ptr;
  //  Set the control points on the edges.
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    index = 3 * (ii * NUM_EDGE_CPTS);
    edge_ptr->set_control_points( &(edgeCtrlPts[index]) );
  } 

  // do the evaluations
  int jj, tindex;
  index = tindex = 0;
    
    for ( ii = 0; ii < numEdge; ii++ ) {
    for ( jj = 0; jj < numLocs; jj++ ) {
      
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_tangent;
      CubitVector *eval_tangent_ptr = NULL;
      if ( tangent != NULL ) 
        eval_tangent_ptr = &eval_tangent;
      edge_ptr = edge_array[ii];
      edge_ptr->evaluate_single(paramLocation[jj],eval_point_ptr);      
      location[index++] = eval_point.x();
      location[index++] = eval_point.y();
      location[index++] = eval_point.z();
      if ( tangent != NULL ) {  
        edge_ptr->evaluate_single_tangent(paramLocation[jj],eval_tangent_ptr);      
        eval_tangent.normalize(); 
        tangent[tindex++] = eval_tangent.x();
        tangent[tindex++] = eval_tangent.y();
        tangent[tindex++] = eval_tangent.z();             
      }      
    }  
  }
  //  delete the temp arrays

  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;

}
void evalBezierEdgeFromTans ( int  numEdge,
int  numVert,
int *  edgeVert,
double *  vert,
double *  edgeVertTang,
int  numLocs,
double *  paramLocation,
double *  location,
double *  tangent 
)

Evaluate a quartic Bezier curve at a specified parametric location given its tangents at the end-points. Evaluates location, and/or tangent.

Parameters:
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations
edgeVertTang- (IN) array of tangents at the edge vertices length 3*(2*numEdge)
numLocs- (IN) number of locations to evaluate per edge
paramLocation- (IN) parametric location to evaluate on each edge length = numLocs
location- (OUT) evaluated point on edge at paramLocation length = numEdge * 3 * numLocs
tangent- (IN/OUT) evaluated tangent at parmLocation. If NULL then will not be evaluated. Return vector is normalized length = numEdge * 3 * numLocs

Definition at line 2023 of file Cholla.cpp.

{
CubitPoint **point_array = new CubitPoint * [numVert];
CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
CubitFacet **facet_array = NULL;
CubitQuadFacet **qfacet_array = NULL;
DLIList<FacetEntity *> facet_list;
int ii, index, numTri, numQuad;
int *triEdge, *quadEdge;
  triEdge = quadEdge = NULL;
  numTri = numQuad = 0;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // set the control points on edges

  int mydebug = 0;
  FILE *fp = NULL;
  if (mydebug)
    fp = fopen("edges.txt", "w");
  CubitFacetEdge *edge_ptr;
  CubitVector T0, T1, P0, P1;
  CubitVector Pi[3];
  CubitPoint *pt0, *pt1;
  for (ii=0; ii<numEdge; ii++)
  {
    index = 6 * ii;
    edge_ptr = edge_array[ii];
    pt0 = edge_ptr->point(0);
    pt1 = edge_ptr->point(1);
    P0 = pt0->coordinates();
    P1 = pt1->coordinates();
    T0.x( edgeVertTang[ index ] );
    T0.y( edgeVertTang[ index + 1] );
    T0.z( edgeVertTang[ index + 2] );
    T1.x( edgeVertTang[ index + 3] );
    T1.y( edgeVertTang[ index + 4] );
    T1.z( edgeVertTang[ index + 5] );
    FacetEvalTool::init_edge_control_points_single(P0, P1, T0, T1, Pi);
    if (mydebug)
    {
      int kk;
      for(kk=0; kk<3; kk++);
      fprintf(fp, "(%d) %.6f %.6f %.6f\n", edge_ptr->id(), P0.x(), P0.y(), P0.z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[0].x(), Pi[0].y(), Pi[0].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[1].x(), Pi[1].y(), Pi[1].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[2].x(), Pi[2].y(), Pi[2].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", P1.x(), P1.y(), P1.z());
    }
    edge_ptr->control_points( Pi, 4 );
  } 
  if (mydebug)
    fclose(fp);

  // do the evaluations
  int jj, tindex;
  index = tindex = 0;
    
  for ( ii = 0; ii < numEdge; ii++ ) {
    for ( jj = 0; jj < numLocs; jj++ ) {
      
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_tangent;
      CubitVector *eval_tangent_ptr = NULL;
      if ( tangent != NULL ) 
        eval_tangent_ptr = &eval_tangent;
      edge_ptr = edge_array[ii];
      edge_ptr->evaluate_single(paramLocation[jj],eval_point_ptr);      
      location[index++] = eval_point.x();
      location[index++] = eval_point.y();
      location[index++] = eval_point.z();
      if ( tangent != NULL ) {  
        edge_ptr->evaluate_single_tangent(paramLocation[jj],eval_tangent_ptr);      
        eval_tangent.normalize(); 
        tangent[tindex++] = eval_tangent.x();
        tangent[tindex++] = eval_tangent.y();
        tangent[tindex++] = eval_tangent.z();             
      }      
    }  
  }
  //  delete the temp arrays

  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;
}
void evalBezierFace ( int  numFace,
int  numEdge,
int  numVert,
int  numVertPerFace,
int *  faceEdge,
int *  edgeVert,
double *  vert,
double *  faceCtrlPts,
double *  edgeCtrlPts,
int  numLocs,
double *  paramLocation,
double *  location,
double *  normal,
double *  deriv 
)

Evaluate a set of quartic Bezier patches at a specified parametric location given its control points. Evaluates location, normal and/or derivative. Expects list of either quads or tris (not both)

Parameters:
numFace- (IN) number of faces to evaluate
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
numVertPerFace-(IN) has value of of 3 or 4, for tris or quads
faceEdge- (IN) array of face to edge indecies (into edgeVert) length numVertPerFace * numFace
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations length 3 * numVert
faceCtrlPts- (IN) array of control points for the faces (same order as faceEdge) if (numFacePerVert == 3) ncp = 6 if (numFacePerVert == 4) ncp = 15 length = 3 * (ncp * numFace)
edgeCtrlPts- (IN) array of control points for the edges (same order as edgeVert array) length 3 * (3 * numEdge)
numLocs- (IN) number of locations to evaluate per face
paramLocation- (IN) parametric location to evaluate on each face if (numFacePerVert == 3) (u,v,w) length = 3 * numLocs if (numFacePerVert == 4) (u,v) length = 2 * numLocs
location- (OUT) evaluated point on surface at paramLocation length = numFace * 3 * numLocs
normal- (IN/OUT) evaluated normal at parmLocation. If NULL then will not be evaluated. Return vector is normalized length = numFace * 3 * numLocs
deriv- (IN/OUT) evaluated derivative at parmLocation with respect to uv or uvw system. If NULL then will not be evaluated. if (numFacePerVert == 3) length = numFace * numLocs * 3*3 (du/dx,du/dy,du/dz, dv/dx,dv/dy,dv/dz, dw/dx,dw/dz,dw/dz) if (numFacePerVert == 4) length = numFace * numLocs * 3*2 (du/dx,du/dy,du/dz, dv/dx,dv/dy,dv/dz)

Definition at line 628 of file Cholla.cpp.

{
    // create arrays of facet entities from the arrays

  int numTri = 0;
  int numQuad = 0;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  int *tri_edge = (numVertPerFace == 3) ? faceEdge : NULL;
  int *quad_edge = (numVertPerFace == 4) ? faceEdge : NULL;
  if (numVertPerFace == 3)
  {
    facet_array = new CubitFacet * [numFace];
    numTri = numFace;
  }
  CubitQuadFacet **qfacet_array = NULL;
  if (numVertPerFace == 4)
  {
    qfacet_array = new CubitQuadFacet * [numFace];
    numQuad = numFace;
  }
  DLIList<FacetEntity *> facet_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, tri_edge, quad_edge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // set the control points on edges

  int index, ii, jj;
  CubitFacetEdge *edge_ptr;
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    index = 3 * (ii * NUM_EDGE_CPTS);
    edge_ptr->set_control_points( &(edgeCtrlPts[index]) );
  }

  // set the control points on triangles

  CubitFacet *facet_ptr;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    index = 3 * (ii * NUM_TRI_CPTS); 
    facet_ptr->set_control_points( &(faceCtrlPts[index]) );
  }

    // set the control points on quads

  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    index = 3 * (ii * NUM_QUAD_CPTS);
    qfacet_ptr->set_control_points( &(faceCtrlPts[index]) );
  }

  // Do the evaluations

  for (ii=0; ii<numTri; ii++)
  {
    for (jj=0; jj<numLocs; jj++)
    {
      facet_ptr = facet_array[ii];
      CubitVector areacoord(paramLocation[jj*3],
                            paramLocation[jj*3+1],
                            paramLocation[jj*3+2]);
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_normal;
      CubitVector *eval_normal_ptr = NULL;
      if (normal != NULL)
      {
        eval_normal_ptr = &eval_normal;
      }
      facet_ptr->evaluate( areacoord, eval_point_ptr, eval_normal_ptr );
      index = 3 * ii * jj;
      location[index] = eval_point.x();
      location[index+1] = eval_point.y();
      location[index+2] = eval_point.z();
      if (normal != NULL)
      {
        normal[index] = eval_normal.x();
        normal[index+1] = eval_normal.y();
        normal[index+2] = eval_normal.z();
      }
    }
  }

  for (ii=0; ii<numQuad; ii++)
  {
    for (jj=0; jj<numLocs; jj++)
    {
      qfacet_ptr = qfacet_array[ii];
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_normal;
      CubitVector *eval_normal_ptr = NULL;
      if (normal != NULL)
        eval_normal_ptr = &eval_normal;
      CubitVector eval_du, eval_dv;
      CubitVector *eval_du_ptr = NULL;
      CubitVector *eval_dv_ptr = NULL;
      if (deriv != NULL)
      {
        eval_du_ptr = &eval_du;
        eval_dv_ptr = &eval_dv;
      }

      qfacet_ptr->evaluate( paramLocation[2*jj], paramLocation[2*jj+1],
                            eval_point_ptr, eval_normal_ptr,
                            eval_du_ptr, eval_dv_ptr);
      index = 3 * ii * jj;
      location[index] = eval_point.x();
      location[index+1] = eval_point.y();
      location[index+2] = eval_point.z();
      if (normal != NULL)
      {
        normal[index] = eval_normal.x();
        normal[index+1] = eval_normal.y();
        normal[index+2] = eval_normal.z();
      }
      if (deriv != NULL)
      {
        index = 6 * ii * jj;
        deriv[index] = eval_du.x();
        deriv[index+1] = eval_du.y();
        deriv[index+2] = eval_du.z();
        deriv[index+3] = eval_dv.x();
        deriv[index+4] = eval_dv.y();
        deriv[index+5] = eval_dv.z();
      }
    }
  }
  
  // delete the temp arrays

  for (ii=0; ii<numQuad; ii++)
    delete qfacet_array[ii];
  for (ii=0; ii<numTri; ii++)
    delete facet_array[ii];
  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
void evalBezierFaceFromNorms ( int  numFace,
int  numEdge,
int  numVert,
int  numVertPerFace,
int *  faceEdge,
int *  edgeVert,
double *  vert,
double *  vertNorms,
double *  edgeVertTang,
int  numLocs,
double *  paramLocation,
double *  location,
double *  normal,
double *  deriv 
)

This is the same as the evalBezierFace except it differes by the input arguments. This function takes a list of normals and tangents at the face vertices and computes bezier control points internally. Normals and tangents should have been computed previously in constructTriNormals or constructQuad Normals. This function is not as computationally efficient as evalBezierFace since it requires Bezier control points to be computed as part of the call - however, it is more memory efficient, requiring fewer variables to be stored with the calling application. The following argument list describes only those arguments that differ from evalBezierFace above.

Parameters:
vertNorms- (IN) array of normals at the face vertices length 3*(numVertPerFace*numFace)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)

Definition at line 809 of file Cholla.cpp.

{
    // create arrays of facet entities from the arrays

  int numTri = 0;
  int numQuad = 0;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  int *triEdge = (numVertPerFace == 3) ? faceEdge : NULL;
  int *quadEdge = (numVertPerFace == 4) ? faceEdge : NULL;
  if (numVertPerFace == 3)
  {
    facet_array = new CubitFacet * [numFace];
    numTri = numFace;
  }
  CubitQuadFacet **qfacet_array = NULL;
  if (numVertPerFace == 4)
  {
    qfacet_array = new CubitQuadFacet * [numFace];
    numQuad = numFace;
  }
  DLIList<FacetEntity *> facet_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // set the normals on triangle vertices

  int index, ii, jj;
  CubitPoint *pt;
  CubitFacet *facet_ptr;
  CubitVector pt_normal;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    for(jj=0; jj<3; jj++)
    {
      index = ii * 9 + (3 * jj);
      pt_normal.x( vertNorms[ index ] );
      pt_normal.y( vertNorms[ index + 1 ] );
      pt_normal.z( vertNorms[ index + 2 ] );
      pt = facet_ptr->point(jj);
      TDFacetBoundaryPoint::add_facet_boundary_point( pt, facet_ptr, pt_normal );
    }
  }

  // set the normals on quad vertices

  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    for(jj=0; jj<4; jj++)
    {
      index = ii * 12 + (3 * jj);
      pt_normal.x( vertNorms[ index ] );
      pt_normal.y( vertNorms[ index + 1 ] );
      pt_normal.z( vertNorms[ index + 2 ] );
      pt = qfacet_ptr->point(jj);
      TDFacetBoundaryPoint::add_facet_boundary_point( pt, qfacet_ptr, pt_normal );
    }
  }

  // set the control points on edges

  int mydebug = 0;
  FILE *fp = NULL;
  if (mydebug)
    fp = fopen("edges.txt", "w");
  CubitFacetEdge *edge_ptr;
  CubitVector N0, N1, T0, T1, P0, P1;
  CubitVector Pi[3];
  CubitPoint *pt0, *pt1;
  for (ii=0; ii<numEdge; ii++)
  {
    index = 6 * ii;
    edge_ptr = edge_array[ii];
    pt0 = edge_ptr->point(0);
    pt1 = edge_ptr->point(1);
    P0 = pt0->coordinates();
    P1 = pt1->coordinates();
    N0 = pt0->normal( edge_ptr );
    N1 = pt1->normal( edge_ptr );
    T0.x( edgeVertTang[ index ] );
    T0.y( edgeVertTang[ index + 1] );
    T0.z( edgeVertTang[ index + 2] );
    T1.x( edgeVertTang[ index + 3] );
    T1.y( edgeVertTang[ index + 4] );
    T1.z( edgeVertTang[ index + 5] );
    FacetEvalTool::init_edge_control_points(P0, P1, N0, N1, T0, T1, Pi);
    if (mydebug)
    {
      int kk;
      for(kk=0; kk<3; kk++);
      fprintf(fp, "(%d) %.6f %.6f %.6f\n", edge_ptr->id(), P0.x(), P0.y(), P0.z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[0].x(), Pi[0].y(), Pi[0].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[1].x(), Pi[1].y(), Pi[1].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", Pi[2].x(), Pi[2].y(), Pi[2].z());
      fprintf(fp, "    %.6f %.6f %.6f\n", P1.x(), P1.y(), P1.z());
    }
    edge_ptr->control_points( Pi, 4 );
  }
  if (mydebug)
    fclose(fp);

  // set the control points on triangles

  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    facet_ptr->init_patch();
  }

    // set the control points on quads

  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    qfacet_ptr->init_patch();
  }

  // Do the evaluations

  index = 0;
  int nindex = 0;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    for (jj=0; jj<numLocs; jj++)
    {  
      CubitVector areacoord(paramLocation[jj*3],
                            paramLocation[jj*3+1],
                            paramLocation[jj*3+2]);
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_normal;
      CubitVector *eval_normal_ptr = NULL;
      if (normal != NULL)
      {
        eval_normal_ptr = &eval_normal;
      }
      facet_ptr->evaluate( areacoord, eval_point_ptr, eval_normal_ptr );
      location[index++] = eval_point.x();
      location[index++] = eval_point.y();
      location[index++] = eval_point.z();
      if (normal != NULL)
      {
        normal[nindex++] = eval_normal.x();
        normal[nindex++] = eval_normal.y();
        normal[nindex++] = eval_normal.z();
      }
    }
  }

  int dindex = 0;
  nindex = index = 0;
  for (ii=0; ii<numQuad; ii++)
  {
    for (jj=0; jj<numLocs; jj++)
    {
      qfacet_ptr = qfacet_array[ii];
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_normal;
      CubitVector *eval_normal_ptr = NULL;
      if (normal != NULL)
        eval_normal_ptr = &eval_normal;
      CubitVector eval_du, eval_dv;
      CubitVector *eval_du_ptr = NULL;
      CubitVector *eval_dv_ptr = NULL;
      if (deriv != NULL)
      {
        eval_du_ptr = &eval_du;
        eval_dv_ptr = &eval_dv;
      }

      qfacet_ptr->evaluate( paramLocation[2*jj], paramLocation[2*jj+1],
                            eval_point_ptr, eval_normal_ptr,
                            eval_du_ptr, eval_dv_ptr);
      location[index++] = eval_point.x();
      location[index++] = eval_point.y();
      location[index++] = eval_point.z();
      if (normal != NULL)
      {
        normal[nindex++] = eval_normal.x();
        normal[nindex++] = eval_normal.y();
        normal[nindex++] = eval_normal.z();
      }
      if (deriv != NULL)
      {
        index = 6 * ii * jj;
        deriv[dindex++] = eval_du.x();
        deriv[dindex++] = eval_du.y();
        deriv[dindex++] = eval_du.z();
        deriv[dindex++] = eval_dv.x();
        deriv[dindex++] = eval_dv.y();
        deriv[dindex++] = eval_dv.z();
      }
    }
  }
  
  // delete the temp arrays

  for (ii=0; ii<numQuad; ii++)
    delete qfacet_array[ii];
  for (ii=0; ii<numTri; ii++)
    delete facet_array[ii];
  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
void importMesh ( const char *  fileName,
int *  resultsIncluded,
double *  angle,
int *  numTri,
int *  numQuad,
int *  numEdge,
int *  numVert,
int **  triEdge,
int **  quadEdge,
int **  edgeVert,
double **  vert,
double **  edgeCtrlPts,
double **  triCtrlPts,
double **  quadCtrlPts 
)

Definition at line 1576 of file Cholla.cpp.

{
  FILE *fp = fopen(fileName, "r");
  assert(fp != NULL);  // couldn't open file for reading
  
  // read the header info

  char version[128];
  char* s = fgets(version, 128, fp);
  if (NULL == s) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(version, "Cholla version 1.0\n") == 0);  // don't recognize file
  char filetime[128];
  s = fgets(filetime, 128, fp); 
  if (NULL == s) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  
  char line[256];
  int num_tri;
  int num_quad;
  int num_edge;
  int num_vert;
  s = fgets(line,256,fp);
  if (NULL == s) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  sscanf(line, "%d %d %d %d %d\n", &num_tri, &num_quad, &num_edge, &num_vert, includeResults); 
  *numTri = num_tri;
  *numQuad = num_quad;
  *numEdge = num_edge;
  *numVert = num_vert;
  int nread = fscanf(fp, "%lf\n", angle);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }

  // triEdge

  *triEdge = new int [num_tri*3];
  int *tri_edge = *triEdge;
  char array_name[128];
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "triEdge") == 0);  // check start of array
  int ii;
  for(ii=0; ii<num_tri; ii++)
  {
    nread = fscanf(fp, "%d %d %d\n", &tri_edge[ii*3], &tri_edge[ii*3+1], &tri_edge[ii*3+2]);
    if (3 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  // quadEdge

  *quadEdge = new int [num_quad*4];
  int *quad_edge = *quadEdge;
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "quadEdge") == 0);  // check start of array
  for(ii=0; ii<num_quad; ii++)
  {
    nread = fscanf(fp, "%d %d %d %d\n", &quad_edge[ii*4], &quad_edge[ii*4+1], 
                                &quad_edge[ii*4+2], &quad_edge[ii*4+3]);
    if (4 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  // edgeVert

  *edgeVert = new int [2*num_edge];
  int *edge_vert = *edgeVert;
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "edgeVert") == 0);  // check start of array
  for (ii=0; ii<num_edge; ii++)
  {
    nread = fscanf(fp, "%d %d\n", &edge_vert[ii*2], &edge_vert[ii*2+1]);
    if (2 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  // vert

  *vert = new double [3*num_vert];
  double *my_vert = *vert;
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "vert") == 0);  // check start of array
  for (ii=0; ii<num_vert; ii++)
  {
    nread = fscanf(fp, "%lf %lf %lf\n", &my_vert[ii*3], &my_vert[ii*3+1], &my_vert[ii*3+2]);
    if (3 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  *edgeCtrlPts = new double [3*num_edge*NUM_EDGE_CPTS];
  if (numTri != 0)
    *triCtrlPts = new double [3*num_tri*NUM_TRI_CPTS];
  if (numQuad != 0)
    *quadCtrlPts = new double [3*num_quad*NUM_QUAD_CPTS];

  double *edge_ctrl_pts = *edgeCtrlPts;
  double *tri_ctrl_pts = *triCtrlPts;
  double *quad_ctrl_pts = *quadCtrlPts;
  if (*includeResults != 0)
  {
     // edge control points
    
    nread = fscanf(fp, "%s\n", array_name);
    if (1 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
    assert(strcmp(array_name, "edgeCtrlPts") == 0);  // check start of array
    for(ii=0; ii<num_edge*NUM_EDGE_CPTS; ii++)
    {
      nread = fscanf(fp, "%lf %lf %lf\n", &edge_ctrl_pts[ii*3], 
                                  &edge_ctrl_pts[ii*3+1], 
                                  &edge_ctrl_pts[ii*3+2]);
      if (3 != nread) {
        PRINT_ERROR("Format error in file %s\n", fileName);
        fclose(fp);
        return;
      }
    }

     // triangle control points
    
    nread = fscanf(fp, "%s\n", array_name);
    if (1 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
    assert(strcmp(array_name, "triCtrlPts") == 0);  // check start of array
    for(ii=0; ii<num_tri*NUM_TRI_CPTS; ii++)
    {
      nread = fscanf(fp, "%lf %lf %lf\n", &tri_ctrl_pts[ii*3], 
                                  &tri_ctrl_pts[ii*3+1], 
                                  &tri_ctrl_pts[ii*3+2]);
      if (3 != nread) {
        PRINT_ERROR("Format error in file %s\n", fileName);
        fclose(fp);
        return;
      }
    }

    // quad control points
    
    nread = fscanf(fp, "%s\n", array_name);
    if (1 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
    assert(strcmp(array_name, "quadCtrlPts") == 0);  // check start of array
    for(ii=0; ii<num_quad*NUM_QUAD_CPTS; ii++)
    {
      nread = fscanf(fp, "%lf %lf %lf\n", &quad_ctrl_pts[ii*3], 
                                  &quad_ctrl_pts[ii*3+1], 
                                  &quad_ctrl_pts[ii*3+2]);
      if (3 != nread) {
        PRINT_ERROR("Format error in file %s\n", fileName);
        fclose(fp);
        return;
      }
    }

  }
  fclose(fp);
}
void importResults ( const char *  fileName,
int *  numEdge,
int *  numTri,
int *  numQuad,
double **  edgeCtrlPts,
double **  triCtrlPts,
double **  quadCtrlPts 
)

Definition at line 1799 of file Cholla.cpp.

{
  FILE *fp = fopen(fileName, "r");
  assert(fp != NULL);  // couldn't open file for reading
  
  // read the header info

  char version[128];
  char* s = fgets(version, 128, fp);
  if (NULL == s) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(version, "Cholla version 1.0 Results\n") == 0);  // don't recognize file
  char filetime[128];
  s = fgets(filetime, 128, fp);
  if (NULL == s) {
    PRINT_ERROR("Format error in mesh file %s\n", fileName);
    fclose(fp);
    return;
  }
  int nread = fscanf(fp, "%d %d %d\n", numEdge, numTri, numQuad);
  if (3 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  int num_edge = *numEdge;
  int num_tri = *numTri;
  int num_quad = *numQuad;
  
  *edgeCtrlPts = new double [3*num_edge*NUM_EDGE_CPTS];
  if (numTri != 0)
    *triCtrlPts = new double [3*num_tri*NUM_TRI_CPTS];
  if (numQuad != 0)
    *quadCtrlPts = new double [3*num_quad*NUM_QUAD_CPTS];

  double *edge_ctrl_pts = *edgeCtrlPts;
  double *tri_ctrl_pts = *triCtrlPts;
  double *quad_ctrl_pts = *quadCtrlPts;

   // edge control points
  
  int ii;
  char array_name[128];
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "edgeCtrlPts") == 0);  // check start of array
  for(ii=0; ii<num_edge*NUM_EDGE_CPTS; ii++)
  {
    nread = fscanf(fp, "%lf %lf %lf\n", &edge_ctrl_pts[ii*3], 
                                &edge_ctrl_pts[ii*3+1], 
                                &edge_ctrl_pts[ii*3+2]);
    if (3 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

   // triangle control points
  
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "triCtrlPts") == 0);  // check start of array
  for(ii=0; ii<num_tri*NUM_TRI_CPTS; ii++)
  {
    nread = fscanf(fp, "%lf %lf %lf\n", &tri_ctrl_pts[ii*3], 
                                &tri_ctrl_pts[ii*3+1], 
                                &tri_ctrl_pts[ii*3+2]);
    if (3 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  // quad control points
  
  nread = fscanf(fp, "%s\n", array_name);
  if (1 != nread) {
    PRINT_ERROR("Format error in file %s\n", fileName);
    fclose(fp);
    return;
  }
  assert(strcmp(array_name, "quadCtrlPts") == 0);  // check start of array
  for(ii=0; ii<num_tri*NUM_QUAD_CPTS; ii++)
  {
    nread = fscanf(fp, "%lf %lf %lf\n", &quad_ctrl_pts[ii*3], 
                                &quad_ctrl_pts[ii*3+1], 
                                &quad_ctrl_pts[ii*3+2]);
    if (3 != nread) {
      PRINT_ERROR("Format error in file %s\n", fileName);
      fclose(fp);
      return;
    }
  }

  fclose(fp);

}
void projToBezierEdge ( int  numEdge,
int  numVert,
int *  edgeVert,
double *  vert,
double *  edgeCtrlPts,
int  numLocs,
double *  xyz,
double *  xyzOnEdge,
double *  tangent,
double *  t_value 
)

Project a 3d point to a quartic Bezier curve at a specified parametric location given its control points.

Parameters:
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations length = 3 * numVert
edgeCtrlPts- (IN) array of control pt locations for each edge in the bezier. The beziers are quartic, so there are 3 control pts per curve in addition to the 2 end pts for each curve for a total of 5 pts per edge. length = 3 * ( 3 * numEdge )
numLocs- (IN) number of locations to evaluate per edge
xyz- (IN) xyz locations to evaluate on each edge length = 3 * numLocs
xyzOnEdge- (OUT) locations on edges closest to input points xyz. length = numEdge * 3 * numLocs
tangent- (IN/OUT) evaluated tangent at parmLocation. If NULL then will not be evaluated. Return vector is normalized length = numEdge * 3 * numLocs
t_value- (OUT) value of the parameter at the projected point length = numEdge * numLocs

Definition at line 2325 of file Cholla.cpp.

{
CubitPoint **point_array = new CubitPoint * [numVert];
CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
CubitFacet **facet_array = NULL;
CubitQuadFacet **qfacet_array = NULL;
DLIList<FacetEntity *> facet_list;
int ii, index, numTri, numQuad;
int *triEdge, *quadEdge;
  triEdge = quadEdge = NULL;
  numTri = numQuad = 0;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // set the control points on edges

  CubitFacetEdge *edge_ptr;
    //CubitVector T0, T1, P0, P1;
    //CubitVector Pi[3];

  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    index = 3 * (ii * NUM_EDGE_CPTS);
    edge_ptr->set_control_points( &(edgeCtrlPts[index]) );
  } 

  // do the projections
  int jj, kk, xyzindex, tindex;
  index = tindex = 0;
  double dsquared, dsquared_test, dderiv, dderiv2, t, t_min = 0.0;
  CubitVector xyz_pt;//, second2142_d;
  t = 0.0;
  dsquared_test =  CUBIT_DBL_MAX;  
  for ( ii = 0; ii < numEdge; ii++ ) {
    edge_ptr = edge_array[ii];
    for ( jj = 0; jj < numLocs; jj++ ) {
      xyzindex = 3*jj;
      xyz_pt.x(xyz[xyzindex]);
      xyz_pt.y(xyz[xyzindex+1]);
      xyz_pt.z(xyz[xyzindex+2]);    
      t = -1.0;
      dsquared_test =  CUBIT_DBL_MAX;  
      //  Get square of distance from xyz to curve at intervals of 0.2
      //  in the parameter t.  Save the closest distance found as a 
      //  starting point for Newton-Raphson iterations.  It was found 
      //  that an interval of 0.5 was too coarse and that the N-R
      //  sometimes converged on a false value.
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_tangent;
      CubitVector *eval_tangent_ptr = &eval_tangent;
      CubitVector second_d;
      CubitVector *second_d_ptr = &second_d;
      for ( kk = 0; kk < 11; kk++ ) {
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        dsquared = ( (xyz_pt.x()-eval_point.x())*(xyz_pt.x()-eval_point.x()) +
                     (xyz_pt.y()-eval_point.y())*(xyz_pt.y()-eval_point.y()) +
                     (xyz_pt.z()-eval_point.z())*(xyz_pt.z()-eval_point.z()) );             
        if ( fabs(dsquared) < fabs(dsquared_test) ) {
          t_min = t;
          dsquared_test = dsquared;
        }      
        t += 0.2;
      }
      double dderiva, dderivb;
      if ( t_min == -1.00 ) {
      //  Check whether the slope changed signs between -1.0 and -0.8.
      //  If so, the min must have occurred in this interval -- set
      //  t_min to -0.9.
        t = -1.0;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderiva = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                       (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                       (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        t = -0.8;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderivb = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                       (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                       (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        if ( dderiva*dderivb < 0.0 ) t_min = -0.9;
   
      } else if ( t_min == 1.00 ) {
      //  Check the other end of the range, similarly.
        t = 1.0;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderiva = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                        (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                        (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        t = 0.8;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderivb = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                        (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                        (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        if ( dderiva*dderivb < 0.0 ) t_min = 0.9;  
      }      
      t = t_min;
      if ( (t > -1.0) && (t < 1.0) ) {
        int mm;
        mm = 0;
        while ( mm < 10 ) {  //  to avoid possible infinite loop
          mm++;
          edge_ptr->evaluate_single(t,eval_point_ptr);      
          edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
          dderiv = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                         (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                         (eval_point.z()-xyz_pt.z())*eval_tangent.z() );

          edge_ptr->evaluate_2nd_derivative(t, second_d_ptr);            
  
          dderiv2 = (eval_point.x()-xyz_pt.x())*second_d.x() + 
                     eval_tangent.x()*eval_tangent.x() +
                    (eval_point.y()-xyz_pt.y())*second_d.y() + 
                     eval_tangent.y()*eval_tangent.y() +
                    (eval_point.z()-xyz_pt.z())*second_d.z() + 
                     eval_tangent.z()*eval_tangent.z();

           t = t - dderiv/dderiv2; // Newton-Raphson

           if ( t < -1.0 ) {
             t = -1.0;
             edge_ptr->evaluate_single(t,eval_point_ptr);      
             edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
             break;
           }
           if ( t > 1.0 ) {
             t = 1.0;
             edge_ptr->evaluate_single(t,eval_point_ptr);      
             edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
             break;
           }
           if ( fabs(dderiv) < 1.e-11 ) break;
        }
      } else {  //  At an endpoint of the paramaterization.
          edge_ptr->evaluate_single(t,eval_point_ptr);       
          edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
      }      
      xyzOnEdge[index++] = eval_point.x();
      xyzOnEdge[index++] = eval_point.y();
      xyzOnEdge[index++] = eval_point.z();
      if ( tangent != NULL ) {  
        eval_tangent.normalize(); 
        tangent[tindex++] = eval_tangent.x();
        tangent[tindex++] = eval_tangent.y();
        tangent[tindex++] = eval_tangent.z();             
      }      
    }  
  } 
   
  *t_value = t;
  
  //  delete the temp arrays

  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;

}
void projToBezierEdgeFromTans ( int  numEdge,
int  numVert,
int *  edgeVert,
double *  vert,
double *  edgeVertTang,
int  numLocs,
double *  xyz,
double *  xyzOnEdge,
double *  tangent 
)

Project to a quartic Bezier curve at a specified parametric location given its tangents at the end-points. Evaluates location, and/or tangent. Finds only one point; in rare cases, more than one closest point might exist.

Parameters:
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations length = 3 * NumVerts
edgeVertTang- (IN) array of tangents at the edge vertices length 3*(2*numEdge)
numLocs- (IN) number of locations to evaluate per edge
xyz- (IN) xyz locations to project to each edge length = 3 * numLocs
xyzOnEdge- (OUT) locations on edges closest to input points xyz. length = numEdge * 3 * numLocs
tangent- (IN/OUT) evaluated tangent at parmLocation. If NULL then will not be evaluated. Return vector is normalized length = numEdge * 3 * numLocs

Definition at line 2131 of file Cholla.cpp.

{
CubitPoint **point_array = new CubitPoint * [numVert];
CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
CubitFacet **facet_array = NULL;
CubitQuadFacet **qfacet_array = NULL;
DLIList<FacetEntity *> facet_list;
int ii, index, numTri, numQuad;
int *triEdge, *quadEdge;
  triEdge = quadEdge = NULL;
  numTri = numQuad = 0;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facet_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }

  // set the control points on edges

  CubitFacetEdge *edge_ptr;
  CubitVector T0, T1, P0, P1;
  CubitVector Pi[3];
  CubitPoint *pt0, *pt1;
  for (ii=0; ii<numEdge; ii++)
  {
    index = 6 * ii;
    edge_ptr = edge_array[ii];
    pt0 = edge_ptr->point(0);
    pt1 = edge_ptr->point(1);
    P0 = pt0->coordinates();
    P1 = pt1->coordinates();
    T0.x( edgeVertTang[ index ] );
    T0.y( edgeVertTang[ index + 1] );
    T0.z( edgeVertTang[ index + 2] );
    T1.x( edgeVertTang[ index + 3] );
    T1.y( edgeVertTang[ index + 4] );
    T1.z( edgeVertTang[ index + 5] );
    FacetEvalTool::init_edge_control_points_single(P0, P1, T0, T1, Pi);

    edge_ptr->control_points( Pi, 4 );
  } 

  // do the projections
  int jj, kk, xyzindex, tindex;
  index = tindex = 0;
  double dsquared, dsquared_test, dderiv, dderiv2, t, t_min = 0.0;
  CubitVector xyz_pt;//, second_d;
  t = 0.0;
  dsquared_test =  CUBIT_DBL_MAX;  
  for ( ii = 0; ii < numEdge; ii++ ) {
    edge_ptr = edge_array[ii];
    for ( jj = 0; jj < numLocs; jj++ ) {
      xyzindex = 3*jj;
      xyz_pt.x(xyz[xyzindex]);
      xyz_pt.y(xyz[xyzindex+1]);
      xyz_pt.z(xyz[xyzindex+2]);    
      t = -1.0;
      dsquared_test =  CUBIT_DBL_MAX;  
      //  Get square of distance from xyz to curve at intervals of 0.2
      //  in the parameter t.  Save the closest distance found as a 
      //  starting point for Newton-Raphson iterations.  It was found 
      //  that an interval of 0.5 was too coarse and that the N-R
      //  sometimes converged on a false value.
      CubitVector eval_point;
      CubitVector *eval_point_ptr = &eval_point;
      CubitVector eval_tangent;
      CubitVector *eval_tangent_ptr = &eval_tangent;
      CubitVector second_d;
      CubitVector *second_d_ptr = &second_d;
      for ( kk = 0; kk < 11; kk++ ) {
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        dsquared = ( (xyz_pt.x()-eval_point.x())*(xyz_pt.x()-eval_point.x()) +
                     (xyz_pt.y()-eval_point.y())*(xyz_pt.y()-eval_point.y()) +
                     (xyz_pt.z()-eval_point.z())*(xyz_pt.z()-eval_point.z()) );             
        if ( fabs(dsquared) < fabs(dsquared_test) ) {
          t_min = t;
          dsquared_test = dsquared;
        }      
        t += 0.2;
      }
      double dderiva, dderivb;
      if ( t_min == -1.00 ) {
      //  Check whether the slope changed signs between -1.0 and -0.8.
      //  If so, the min must have occurred in this interval -- set
      //  t_min to -0.9.
        t = -1.0;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderiva = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                       (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                       (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        t = -0.8;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderivb = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                       (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                       (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        if ( dderiva*dderivb < 0.0 ) t_min = -0.9;
   
      } else if ( t_min == 1.00 ) {
      //  Check the other end of the range, similarly.
        t = 1.0;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderiva = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                        (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                        (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        t = 0.8;
        edge_ptr->evaluate_single(t,eval_point_ptr);      
        edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
        dderivb = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                        (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                        (eval_point.z()-xyz_pt.z())*eval_tangent.z() );
        if ( dderiva*dderivb < 0.0 ) t_min = 0.9;  
      }      
      t = t_min;
      if ( (t > -1.0) && (t < 1.0) ) {
        int mm;
        mm = 0;
        while ( mm < 10 ) {  //  to avoid possible infinite loop
          mm++;
          edge_ptr->evaluate_single(t,eval_point_ptr);      
          edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
          dderiv = 2.0*( (eval_point.x()-xyz_pt.x())*eval_tangent.x() +
                         (eval_point.y()-xyz_pt.y())*eval_tangent.y() +
                         (eval_point.z()-xyz_pt.z())*eval_tangent.z() );

          edge_ptr->evaluate_2nd_derivative(t, second_d_ptr);            
  
          dderiv2 = (eval_point.x()-xyz_pt.x())*second_d.x() + 
                     eval_tangent.x()*eval_tangent.x() +
                    (eval_point.y()-xyz_pt.y())*second_d.y() + 
                     eval_tangent.y()*eval_tangent.y() +
                    (eval_point.z()-xyz_pt.z())*second_d.z() + 
                     eval_tangent.z()*eval_tangent.z();

           t = t - dderiv/dderiv2; // Newton-Raphson

           if ( t < -1.0 ) {
             t = -1.0;
             edge_ptr->evaluate_single(t,eval_point_ptr);      
             edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
             break;
           }
           if ( t > 1.0 ) {
             t = 1.0;
             edge_ptr->evaluate_single(t,eval_point_ptr);      
             edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
             break;
           }
           if ( fabs(dderiv) < 1.e-11 ) break;
        }
      } else {  //  At an endpoint of the paramaterization.
          edge_ptr->evaluate_single(t,eval_point_ptr);       
          edge_ptr->evaluate_single_tangent(t,eval_tangent_ptr);      
      }      
      xyzOnEdge[index++] = eval_point.x();
      xyzOnEdge[index++] = eval_point.y();
      xyzOnEdge[index++] = eval_point.z();
      if ( tangent != NULL ) {  
        eval_tangent.normalize(); 
        tangent[tindex++] = eval_tangent.x();
        tangent[tindex++] = eval_tangent.y();
        tangent[tindex++] = eval_tangent.z();             
      }      
    }  
  }  

  //  delete the temp arrays

  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;

}
void projToBezierFace ( int  numFace,
int  numEdge,
int  numVert,
int  numVertPerFace,
int *  faceEdge,
int *  edgeVert,
double *  vert,
double *  faceCtrlPts,
double *  edgeCtrlPts,
int  numLocs,
double *  xyz,
int  specify_tol,
double  converge_tol,
double *  xyzOnFace,
double *  normal,
double *  deriv 
)

Project a set of x-y-z locations to Bezier patches. Finds the closest point on one of the patches. Evaluates location, normal and/or derivative. Expects list of either quads or tris (not both)

Parameters:
numFace- (IN) number of faces to evaluate
numEdge- (IN) number of edges on the faces
numVert- (IN) number of vertices
numVertPerFace-(IN) has value of of 3 or 4, for tris or quads
faceEdge- (IN) array of face to edge indecies (into edgeVert) length numVertPerFace * numFace
edgeVert- (IN) array of edge to vertex indecies (into vert) length 2 * numEdge
vert- (IN) array of vertex locations length 3 * numVert
faceCtrlPts- (IN) array of control points for the faces (same order as faceEdge) if (numFacePerVert == 3) ncp = 6 if (numFacePerVert == 4) ncp = 15 length = 3 * (ncp * numFace)
edgeCtrlPts- (IN) array of control points for the edges (same order as edgeVert array) length 3 * (3 * numEdge)
numLocs- (IN) number of locations to evaluate per face
xyz- (IN) xyz locations to evaluate on each face length = 3 * numLocs
specify_tol- (IN) 1 = a converge_tol is specified, 0 = a converge_tol is not specified. A default tol will be computed and used.
converge_tol- (IN) The convergance tolerance for this projection. Will be ignored if specify_tol == 0
xyzOnFace- (OUT) locations on patches closest to input points xyz. length = 3 * numLocs
normal- (IN/OUT) evaluated normals at xyz. If NULL then will not be evaluated. Return vector is normalized length = 3 * numLocs
deriv- (IN/OUT) evaluated derivatives at xyz with respect to uv or uvw system. If NULL then will not be evaluated. if (numFacePerVert == 3) length = numLocs * 3*3 (du/dx,du/dy,du/dz, dv/dx,dv/dy,dv/dz, dw/dx,dw/dz,dw/dz) if (numFacePerVert == 4) length = numLocs * 3*2 (du/dx,du/dy,du/dz, dv/dx,dv/dy,dv/dz)

Definition at line 1048 of file Cholla.cpp.

{
    // create arrays of facet entities from the arrays

  int numTri = 0;
  int numQuad = 0;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  int *tri_edge = (numVertPerFace == 3) ? faceEdge : NULL;
  int *quad_edge = (numVertPerFace == 4) ? faceEdge : NULL;
  if (numVertPerFace == 3)
  {
    facet_array = new CubitFacet * [numFace];
    numTri = numFace;
  }
  CubitQuadFacet **qfacet_array = NULL;
  if (numVertPerFace == 4)
  {
    qfacet_array = new CubitQuadFacet * [numFace];
    numQuad = numFace;
  }
  DLIList<FacetEntity *> facetentity_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, quad_edge, tri_edge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facetentity_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }
  DLIList<CubitFacet *> facet_list;
  CAST_LIST(facetentity_list, facet_list, CubitFacet);

  // set the control points on edges

  double edgelen;
  double compare_tol = 0.0;
  int index, ii;
  CubitFacetEdge *edge_ptr;
  for (ii=0; ii<numEdge; ii++)
  {
    edge_ptr = edge_array[ii];
    index = 3 * (ii * NUM_EDGE_CPTS);
    edge_ptr->set_control_points( &(edgeCtrlPts[index]) );
    if ( !specify_tol )
    {
        edgelen = edge_ptr->length();
        compare_tol += edgelen; 
    }
  }
  if ( specify_tol )
  {
      compare_tol = converge_tol;
  }
  else
  {
      compare_tol /= numEdge;
      compare_tol *= 1.0e-3;
  }

  // set the control points on triangles

  CubitFacet *facet_ptr;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    index = 3 * (ii * NUM_TRI_CPTS); 
    facet_ptr->set_control_points( &(faceCtrlPts[index]) );
  }

  // set the control points on quads

  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    index = 3 * (ii * NUM_QUAD_CPTS);
    qfacet_ptr->set_control_points( &(faceCtrlPts[index]) );
  }

  // Do the projections

  CubitFacet *last_facet = NULL;
  int interp_order = 4;
  CubitBoolean trim = CUBIT_TRUE;
  CubitBoolean outside;
  for (ii=0; ii<numLocs; ii++)
  {
    CubitVector cur_location(xyz[ii*3],
                             xyz[ii*3+1],
                             xyz[ii*3+2]);
    CubitVector eval_point;
    CubitVector *eval_point_ptr = &eval_point;
    CubitVector eval_normal;
    CubitVector *eval_normal_ptr = NULL;
    if (normal != NULL)
    {
      eval_normal_ptr = &eval_normal;
    }
    FacetEvalTool::project_to_facets(facet_list, last_facet,
                                     interp_order, compare_tol,
                                     cur_location, trim,
                                     &outside, eval_point_ptr,
                                     eval_normal_ptr);
    index = 3 * ii;
    xyzOnFace[index] = eval_point.x();
    xyzOnFace[index+1] = eval_point.y();
    xyzOnFace[index+2] = eval_point.z();
    if (normal != NULL)
    {
      normal[index] = eval_normal.x();
      normal[index+1] = eval_normal.y();
      normal[index+2] = eval_normal.z();
    }
  }

  // no derivatives yet!!

  
  // delete the temp arrays

  for (ii=0; ii<numQuad; ii++)
    delete qfacet_array[ii];
  for (ii=0; ii<numTri; ii++)
    delete facet_array[ii];
  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
void projToBezierFaceFromNorms ( int  numFace,
int  numEdge,
int  numVert,
int  numVertPerFace,
int *  faceEdge,
int *  edgeVert,
double *  vert,
double *  vertNorms,
double *  edgeVertTang,
int  numLocs,
double *  xyz,
int  specify_tol,
double  converge_tol,
double *  xyzOnFace,
double *  normal,
double *  deriv 
)

This is the same as the projToBezierFace except it differes by the input arguments. This function takes a list of normals and tangents at the face vertices and computes bezier control points internally. Normals and tangents should have been computed previously in constructTriNormals or constructQuadNormals. This function is not as computationally efficient as evalBezierFace since it requires Bezier control points to be computed as part of the call - however, it is more memory efficient, requiring fewer variables to be stored with the calling application. The following argument list describes only those arguments that differ from projToBezierFace above.

Parameters:
vertNorms- (IN) array of normals at the face vertices length 3*(numVertPerFace*numFace)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge)

Definition at line 1208 of file Cholla.cpp.

{
      // create arrays of facet entities from the arrays

  int numTri = 0;
  int numQuad = 0;
  CubitPoint **point_array = new CubitPoint * [numVert];
  CubitFacetEdge **edge_array = new CubitFacetEdge * [numEdge];
  CubitFacet **facet_array = NULL;
  int *triEdge = (numVertPerFace == 3) ? faceEdge : NULL;
  int *quadEdge = (numVertPerFace == 4) ? faceEdge : NULL;
  if (numVertPerFace == 3)
  {
    facet_array = new CubitFacet * [numFace];
    numTri = numFace;
  }
  CubitQuadFacet **qfacet_array = NULL;
  if (numVertPerFace == 4)
  {
    qfacet_array = new CubitQuadFacet * [numFace];
    numQuad = numFace;
  }
  DLIList<FacetEntity *> facetentity_list;
  CubitStatus stat = CUBIT_SUCCESS;
  stat = build_facets(numTri, numQuad, numEdge, numVert, triEdge, quadEdge, 
                      edgeVert, vert, point_array, edge_array, facet_array,
                      qfacet_array, facetentity_list);
  if (CUBIT_SUCCESS != stat) {
    PRINT_ERROR("Failed to build facets.\n");
    return;
  }
  DLIList<CubitFacet *> facet_list;
  CAST_LIST(facetentity_list, facet_list, CubitFacet);

  // set the normals on triangle vertices

  int index, ii, jj;
  CubitPoint *pt;
  CubitFacet *facet_ptr;
  CubitVector pt_normal;
  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    for(jj=0; jj<3; jj++)
    {
      index = ii * 9 + (3 * jj);
      pt_normal.x( vertNorms[ index ] );
      pt_normal.y( vertNorms[ index + 1 ] );
      pt_normal.z( vertNorms[ index + 2 ] );
      pt = facet_ptr->point(jj);
      TDFacetBoundaryPoint::add_facet_boundary_point( pt, facet_ptr, pt_normal );
    }
  }

  // set the normals on quad vertices

  CubitQuadFacet *qfacet_ptr;
  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    for(jj=0; jj<4; jj++)
    {
      index = ii * 12 + (3 * jj);
      pt_normal.x( vertNorms[ index ] );
      pt_normal.y( vertNorms[ index + 1 ] );
      pt_normal.z( vertNorms[ index + 2 ] );
      pt = qfacet_ptr->point(jj);
      TDFacetBoundaryPoint::add_facet_boundary_point( pt, qfacet_ptr, pt_normal );
    }
  }

  // set the control points on edges

  double edgelen;
  double compare_tol = 0.0;
  CubitFacetEdge *edge_ptr;
  CubitVector N0, N1, T0, T1, P0, P1;
  CubitVector Pi[3];
  CubitPoint *pt0, *pt1;
  for (ii=0; ii<numEdge; ii++)
  {
    index = 6 * ii;
    edge_ptr = edge_array[ii];
    pt0 = edge_ptr->point(0);
    pt1 = edge_ptr->point(1);
    P0 = pt0->coordinates();
    P1 = pt1->coordinates();
    N0 = pt0->normal( edge_ptr );
    N1 = pt1->normal( edge_ptr );
    T0.x( edgeVertTang[ index ] );
    T0.y( edgeVertTang[ index + 1] );
    T0.z( edgeVertTang[ index + 2] );
    T1.x( edgeVertTang[ index + 3] );
    T1.y( edgeVertTang[ index + 4] );
    T1.z( edgeVertTang[ index + 5] );
    FacetEvalTool::init_edge_control_points(P0, P1, N0, N1, T0, T1, Pi);
    edge_ptr->control_points( Pi, 4 );
    if ( !specify_tol )
    {
        edgelen = edge_ptr->length();
        compare_tol += edgelen; 
    }
  }
  if ( specify_tol )
  {
      compare_tol = converge_tol;
  }
  else
  {
      compare_tol /= numEdge;
      compare_tol *= 1.0e-3;
  }

  // set the control points on triangles

  for (ii=0; ii<numTri; ii++)
  {
    facet_ptr = facet_array[ii];
    facet_ptr->init_patch();
  }

    // set the control points on quads

  for (ii=0; ii<numQuad; ii++)
  {
    qfacet_ptr = qfacet_array[ii];
    qfacet_ptr->init_patch();
  }

    // Do the projections

  CubitFacet *last_facet = NULL;
  int interp_order = 4;
  CubitBoolean trim = CUBIT_TRUE;
  CubitBoolean outside;
  
  for (ii=0; ii<numLocs; ii++)
  {
    CubitVector cur_location(xyz[ii*3],
                             xyz[ii*3+1],
                             xyz[ii*3+2]);
    CubitVector eval_point;
    CubitVector *eval_point_ptr = &eval_point;
    CubitVector eval_normal;
    CubitVector *eval_normal_ptr = NULL;
    if (normal != NULL)
    {
      eval_normal_ptr = &eval_normal;
    }
    FacetEvalTool::project_to_facets(facet_list, last_facet,
                                     interp_order, compare_tol,
                                     cur_location, trim,
                                     &outside, eval_point_ptr,
                                     eval_normal_ptr);
      //double dist = cur_location.distance_between(eval_point);
    index = 3 * ii;
    xyzOnFace[index] = eval_point.x();
    xyzOnFace[index+1] = eval_point.y();
    xyzOnFace[index+2] = eval_point.z();
    if (normal != NULL)
    {
      normal[index] = eval_normal.x();
      normal[index+1] = eval_normal.y();
      normal[index+2] = eval_normal.z();
    }
  }

  // no derivatives yet!!

  // delete the temp arrays

  for (ii=0; ii<numQuad; ii++)
    delete qfacet_array[ii];
  for (ii=0; ii<numTri; ii++)
    delete facet_array[ii];
  for (ii=0; ii<numEdge; ii++)
    delete edge_array[ii];
  for (ii=0; ii<numVert; ii++)
    delete point_array[ii];
  delete [] point_array;
  delete [] edge_array;
  if (facet_array)
    delete [] facet_array; 
  if (qfacet_array)
    delete [] qfacet_array; 
}
CubitStatus readMBGNormalFile ( const char *  filename,
int *  numTri,
int *  numQuad,
int *  numEdge,
int **  edgeVert,
double **  edgeVertTang,
int **  triVert,
double **  triVertNorms,
int **  quadVert,
double **  quadVertNorms 
)

Return normal and tangents for on a list of quad faces a given a file containing the geometric normals and tangents. This returns all of the data in the file rather than just for the specified input elements and edges like constructQuadNormalsFromFile and constructTriNormalsFromFile

Parameters:
filename- (IN) full path and name of the text file containing the geometric surface normals and tangents. This file is output from Cubit when exporting an exodus file.
numTri- (OUT) number of quad faces
numQuad- (OUT) number of quad faces
numEdge- (OUT) number of edges
edgeVert- (OUT) array of vertices on each edge. length 2*numEdge (Must be freed by caller)
edgeVertTang- (OUT) array of tangents at the edge vertices length 3*(2*numEdge) (Must be freed by caller)
TriVert- (OUT) array of vertices on each tri. length 3*numTri
TriVertNorms- (OUT) array of normals at the tri vertices length 3*(4*numTri) (Must be freed by caller)
QuadVert- (OUT) array of vertices on each quad. length 3*numQuad
QuadVertNorms- (OUT) array of normals at the quad vertices length 3*(4*numQuad) (Must be freed by caller)

Definition at line 3065 of file Cholla.cpp.

{
#define MAX_FILE_LINE 512

    int num_t = 0;
    int num_q = 0;
    int curr_quad = 0;
    int curr_tri = 0;
    int num_e = 0;
    int n[4];

    if ( num_tris           ) *num_tris = 0;
    if ( num_quads          ) *num_quads = 0;
    if ( num_edges          ) *num_edges = 0;
    if ( edge_nodes         ) *edge_nodes = NULL;
    if ( edge_node_tangents ) *edge_node_tangents = NULL;
    if ( tri_nodes          ) *tri_nodes = NULL;
    if ( quad_nodes         ) *quad_nodes = NULL;
    if ( tri_node_normals   ) *tri_node_normals = NULL;
    if ( quad_node_normals  ) *quad_node_normals = NULL;

    if ( strlen( filename ) == 0 )
    {
        PRINT_ERROR(" No filename specified\n");
        return CUBIT_FAILURE;
    }

    ifstream geom_file( filename );

    char fileline[MAX_FILE_LINE];

    while ( geom_file.getline( fileline, MAX_FILE_LINE ) )
    {
        int block_id,
            num_corners,
            num_elems;

        if ( !strcmp( fileline, END_OF_BLOCKS ) ) break;
        if ( 3 != sscanf( fileline, "BLK %d %d %d",
                          &block_id, &num_corners, &num_elems ) )
        {
            PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
            geom_file.close();
            return CUBIT_FAILURE;
        }

        if ( num_corners == 3 )
        {
            checkMemoryAllocations( num_corners, num_elems, &num_t, tri_nodes,
                                    tri_node_normals );
        }
        else if ( num_corners == 4 )
        {
            checkMemoryAllocations( num_corners, num_elems, &num_q, quad_nodes,
                                    quad_node_normals );
        }
        else
        {
            PRINT_ERROR( "MBG Normal file can only support quads and tris.\n" );
            geom_file.close();
            return CUBIT_FAILURE;
        }

        for ( int ielem = 0; ielem < num_elems; ielem++ )
        {
            int *this_nodes = NULL;
            double *this_norms = NULL;

            if ( !geom_file.getline( fileline, MAX_FILE_LINE ) )
            {
                PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                geom_file.close();
                return CUBIT_FAILURE;
            }

            if ( num_corners == 4 )
            {
                if ( quad_nodes        ) this_nodes = &((*quad_nodes       )[4     * curr_quad]);
                if ( quad_node_normals ) this_norms = &((*quad_node_normals)[4 * 3 * curr_quad]);
                curr_quad++;
            }
            else if ( num_corners == 3 )
            {
                if ( tri_nodes        ) this_nodes = &((*tri_nodes       )[3     * curr_tri]);
                if ( tri_node_normals ) this_norms = &((*tri_node_normals)[3 * 3 * curr_tri]);
                curr_tri++;
            }
            if ( ( num_corners == 4 && 4 != sscanf( fileline, "%d %d %d %d",
                                                    &n[0], &n[1], &n[2], &n[3]  ) ) ||
                 ( num_corners == 3 && 3 != sscanf( fileline, "%d %d %d",
                                                    &n[0], &n[1], &n[2] ) ) )
            {
                PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                geom_file.close();
                return CUBIT_FAILURE;
            }

            if ( this_nodes )
                memcpy( this_nodes, n, num_corners * sizeof( int ) );

            // Read in the surface normals at the vertices of this element.

            for ( int icorner = 0; icorner < num_corners; icorner++ )
            {
                if ( !geom_file.getline( fileline, MAX_FILE_LINE ) )
                {
                    PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                    geom_file.close();
                    return CUBIT_FAILURE;
                }
                if ( this_norms )
                {
                    double norm[3];

                    if ( 3 != sscanf( fileline, "%lf %lf %lf", &norm[0], &norm[1], &norm[2] ) )
                    {
                        PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                        geom_file.close();
                        return CUBIT_FAILURE;
                    }
                    memcpy( &(this_norms[icorner * 3]), norm, 3 * sizeof( double ) );
                }
            }
        }
    }

    if ( !geom_file.getline( fileline, MAX_FILE_LINE ) )
    {
        PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
        geom_file.close();
        return CUBIT_FAILURE;
    }

    if ( 1 != sscanf( fileline, "%d", &num_e ) )
    {
        PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
        geom_file.close();
        return CUBIT_FAILURE;
    }

    if ( edge_nodes || edge_node_tangents )
    {
        if ( edge_nodes         ) *edge_nodes         = new int [ 2 * num_e ];
        if ( edge_node_tangents ) *edge_node_tangents = new double [3 * 2 * num_e];

        for ( int iedge = 0; iedge < num_e; iedge++ )
        {
            if ( !geom_file.getline( fileline, MAX_FILE_LINE ) )
            {
                PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                geom_file.close();
                return CUBIT_FAILURE;
            }
            if ( 2 != sscanf( fileline, "%d %d", &n[0], &n[1] ) )
            {
                PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                geom_file.close();
                return CUBIT_FAILURE;
            }

            for ( int iend = 0; iend < 2; iend++ )
            {
                double d[3];

                if ( edge_nodes )
                {
                    (*edge_nodes)[iedge * 2 + iend ] = n[iend];
                }

                if ( !geom_file.getline( fileline, MAX_FILE_LINE ) )
                {
                    PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                    geom_file.close();
                    return CUBIT_FAILURE;
                }
                if ( 3 != sscanf( fileline, "%lf %lf %lf", &d[0], &d[1], &d[2] ) )
                {
                    PRINT_ERROR( "MBG Normal file has incorrect file format\n" );
                    geom_file.close();
                    return CUBIT_FAILURE;
                }

                int index = ((iedge*2) + iend) * 3;
                if ( edge_node_tangents )
                {
                    (*edge_node_tangents)[ index     ] = d[0];
                    (*edge_node_tangents)[ index + 1 ] = d[1];
                    (*edge_node_tangents)[ index + 2 ] = d[2];
                }
            }
        }
    }

    if ( num_quads ) *num_quads = num_q;
    if ( num_tris  ) *num_tris  = num_t;
    if ( num_edges ) *num_edges = num_e;

    geom_file.close();
    return CUBIT_SUCCESS;
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines