/***********************************************************************
*
* ELMER, A Computational Fluid Dynamics Program.
*
* Copyright 1st April 1995 - , Center for Scientific Computing,
* Finland.
*
* All rights reserved. No part of this program may be used,
* reproduced or transmitted in any form or by any means
* without the written permission of CSC.
*
* Address: Center for Scientific Computing
* Tietotie 6, P.O. BOX 405
* 02101 Espoo, Finland
* Tel. +358 0 457 2001
* Telefax: +358 0 457 2302
* EMail: Jari.Jarvinen@csc.fi
************************************************************************/
/***********************************************************************
Program: ELMER Front
Module: ecif_inputIges.cpp
Language: C++
Date: 01.10.98
Version: 1.00
Author(s): Martti Verho
Revisions:
Abstract: Implementation
************************************************************************/
#include "ecif_body.h"
#include "ecif_body2D.h"
#include "ecif_body3D.h"
#include "ecif_bodyElement.h"
#include "ecif_bodyElement1D.h"
#include "ecif_bodyElement2D.h"
#include "ecif_bodyElement3D.h"
#include "ecif_geometry.h"
#include "ecif_inputIges.h"
#include "ecif_model.h"
const int IGES_LINE_LEN = 80;
const int SEC_ID_POS = 72;
const int DIR_FLD_LEN = 8;
const int DATA_PART_LEN = 64;
char DATA_END = ';';
char DATA_SEP = ',';
// Global buffers
char fieldBuffer[1+DIR_FLD_LEN];
char lineBuffer[1+IGES_LINE_LEN];
char dataBuffer[1+DATA_PART_LEN];
char dataFieldBuffer[1+DATA_PART_LEN];
int statusNbrBuffer[4];
char statusFldBuffer[3];
// Constructor
IgesStatusField::IgesStatusField()
{
blankFlag = 0;
subordFlag = 0;
useFlag = 0;
hrchFlag = 0;
}
// Split character format data-field into status number values
void
IgesStatusField::setValues(char* data_str)
{
for(int i=0; i<4; i++) {
statusFldBuffer[0] = data_str[2*i];
statusFldBuffer[1] = data_str[2*i + 1];
statusNbrBuffer[i] = atoi(statusFldBuffer);
}
blankFlag = statusNbrBuffer[0];
subordFlag = statusNbrBuffer[1];
useFlag = statusNbrBuffer[2];
hrchFlag = statusNbrBuffer[3];
}
// Constructor
IgesDirectoryEntry::IgesDirectoryEntry()
{
id = 0;
entNbr = 0;
startLine = 0;
nofLines = 0;
colorNbr = DEFAULT_COLOR_INDEX;
formNbr = 0;
transfId = 0;
canBeBody = false;
referingId = 0;
body = NULL;
}
// Constructor
InputIges::InputIges(enum ecif_modelDimension m_dim,
ifstream& in_file, char* in_filename):
Input(m_dim, in_file, in_filename)
{
modelDimension = inputDimension;
directory = new IgesDirectory;
paramSecLine = 0;
paramSecStart = 0;
}
// Method adds new directory entry to the container "directory"
int
InputIges::addToDirectory(IgesDirectoryEntry* dir_entry)
{
int dir_id = dir_entry->id;
(*directory)[dir_id] = dir_entry;
return dir_id;
}
// Method checks if argument strin stream buffer is 'empty', it
// means if there are no data values in the line.
// NOTE: we suppouse that there are no blanks among data values !!!***!!!
bool
InputIges::dataLineStrmIsEmpty(istrstream& data_line)
{
char c = data_line.peek();
if (c == EOF || c == ' ')
return true;
return false;
}
bool
InputIges::checkEntryReferences()
{
//--Go to the start position of the parameter (= data) section.
infile.seekg(paramSecStart - infile.tellg(), ios::cur);
paramSecLine = 1;
bool check_only_status = true;
//--Loop through stored dircetory entities and update references to
// other directory entries
// This is needed when we decide which entries defines bodies!
IgesDirectory::iterator pos = directory->begin();
bool ok;
while (pos != directory->end()) {
IgesDirectoryEntry* de = (*pos++).second;
switch (de->entNbr) {
case 100: ok = read_100(de, check_only_status); break;
case 102: ok = read_102(de, check_only_status); break;
case 106: ok = read_106(de, check_only_status); break;
case 141: ok = read_141(de, check_only_status); break;
case 142: ok = read_142(de, check_only_status); break;
case 143: ok = read_143(de, check_only_status); break;
case 144: ok = read_144(de, check_only_status); break;
default: ok = true; break;
}
if (!ok) {
return false;
}
}
return true;
}
bool
InputIges::createBodies()
{
IgesDirectory::iterator pos;
// First create bodies
pos = directory->begin();
while (pos != directory->end()) {
IgesDirectoryEntry* de = (*pos++).second;
if ( !de->canBeBody || de->referingId > 0 ) {
continue;
}
Body* body;
if ( modelDimension == ECIF_2D ) {
body = new Body2D();
} else {
body = new Body3D();
}
model->addBody(body);
de->body = body;
}
// Next set parent bodies for the component elements
pos = directory->begin();
while (pos != directory->end()) {
IgesDirectoryEntry* de = (*pos++).second;
if ( de->referingId <= 0 ) {
continue;
}
IgesDirectoryEntry* ref_de = getDirectoryEntry(de->referingId);
de->body = ref_de->body;
}
return true;
}
// Method finds out the dimension of a Iges format Cad-model.
// One way to do this is to check if one of the (x,y,z) values
// is constant for all vertices. In this case model would be 2D.
// Otherwise it is 3D
//
enum ecif_modelDimension
InputIges::findCadModelDimension() {
// Currently only 2D
return ECIF_2D;
//return ECIF_3D;
}
// Method reads one data field from string stream argument "data-line"
// into buffer "buffer".
void
InputIges::getDataField(istrstream*& data_line, char* buffer)
{
// If there is no more data in the data-buffer, read next data-line
if (dataLineStrmIsEmpty(*data_line)) {
delete data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
}
data_line->getline(buffer, DATA_PART_LEN, DATA_SEP);
}
// Methods retrieves directory entry from the container "directory"
// using the argument "entry-id" as teh key.
IgesDirectoryEntry*
InputIges::getDirectoryEntry(int entry_id)
{
IgesDirectoryEntry* de = (*directory)[entry_id];
return de;
}
// Method reads directory field number "fld_nbr" into buffer "fld_buffer"
// Data in in the buffer "line_buffer"
void
InputIges::getDirectoryField(int fld_nbr, char* line_buffer, char* fld_buffer)
{
strncpy(fld_buffer, line_buffer + (fld_nbr-1) * DIR_FLD_LEN, DIR_FLD_LEN);
}
// Method locates the starting position of the paramter lines
// (data lines) where the argument directory entry is pointing to.
// First line is read int global buffer "lineBuffer"
void
InputIges::locateParamEntry(IgesDirectoryEntry* de)
{
int delta = de->startLine - paramSecLine;
if (delta == 0)
return;
else if (delta > 0) {
paramSecLine += delta;
readFileLine(infile, lineBuffer, delta);
return;
}
else {
infile.seekg(paramSecStart, ios::beg);
paramSecLine = de->startLine;
readFileLine(infile, lineBuffer, paramSecLine - 1);
}
}
// Read those entries which define body elements
bool
InputIges::readBodyElements()
{
//-Go to the start position of the parameter (= data) section.
infile.seekg(paramSecStart - infile.tellg(), ios::cur);
paramSecLine = 1;
// Loop through directory entries
IgesDirectory::iterator pos = directory->begin();
while (pos != directory->end()) {
IgesDirectoryEntry* de = (*pos++).second;
// If this entry is not in the model at all!
if ( de->body == NULL ) {
continue;
}
bool ok;
switch(de->entNbr) {
case 100: ok = read_100(de); break;
case 106: ok = read_106(de); break;
case 110: ok = read_110(de); break;
case 126: ok = read_126(de); break;
case 128: ok = read_128(de); break;
default: ok = true; break;
}
if (!ok) {
return false;
}
}
return true;
}
// Method reads all bodies in the Iges input file.
// Returns the number of the bodies read.
bool
InputIges::readCadGeometry()
{
bool result;
//--Read directory section and find the start position of the
// of parameters-section in the file.
// Paramter-section line-counter is set to 0.
// NOTE: This counter is updated by: readDataLine and
// locateParamEntry functions.
paramSecStart = readDirectory();
//--If model type is unknown
if (modelDimension == ECIF_ND) {
modelDimension = findCadModelDimension();
}
//--Update entry references ans states
checkEntryReferences();
//--Create bodies in each entry which defines a body
createBodies();
//--Read body elements
readBodyElements();
// After reading all body-information, data can be checked!
//result = this->model->checkBodies();
// if (!modelIsOk)
// exit(1);
return true;
}
// Method reads header information from the input file.
// (this is model level information (units etc.))
bool
InputIges::readCadHeader()
{
return true;
}
// Method reads one data-line into buffer "data_buf" from Iges Cad-file.
// NOTE: end character (like ;) for the group of data lines
// is not read from the file.
void
InputIges::readDataLine(char* line_buf, char* data_buf)
{
readFileLine(infile, line_buf);
char* tmp = line_buf;
int i = 0;
// Copy data-part into data_buf. Don't copy data-end
// separator character (normally ';')
while (i < DATA_PART_LEN && *tmp != DATA_END)
data_buf[i++] = *tmp++;
data_buf[i] = '\0';
// If we working om parameters-section, increase the
// line counter.
if (paramSecLine > 0)
paramSecLine++;
}
// Method reads all (interesting)directory entries from Iges Cad-file
// and stores them into attribute "directory" (container)
int
InputIges::readDirectory()
{
fieldBuffer[1+DIR_FLD_LEN] = '\0';
lineBuffer[SEC_ID_POS] = ' ';
while (!infile.eof() && lineBuffer[SEC_ID_POS] != 'D')
readFileLine(infile, lineBuffer);
if (infile.eof())
return 0;
IgesDirectoryEntry* de;
int cur_file_pos = infile.tellg();
while (!infile.eof() && lineBuffer[SEC_ID_POS] == 'D') {
de = readDirectoryEntry(lineBuffer);
//-Add geometry-use types to directory
//if (de->status.useFlag == 0)
// addToDirectory(de);
// Currently all entries are added to directory.
// The problem is: what entries could be excluded? !!!
addToDirectory(de);
//-Read the first line of next entry
cur_file_pos = infile.tellg();
readFileLine(infile, lineBuffer);
}
return cur_file_pos;
}
IgesDirectoryEntry*
InputIges::readDirectoryEntry(char* dir_line)
{
char* tmp;
IgesDirectoryEntry* dir_entry = new IgesDirectoryEntry;
// First directory-entry line
// ==========================
//--Entity type number
getDirectoryField(1, dir_line, fieldBuffer);
dir_entry->entNbr = atoi(fieldBuffer);
//--Id
getDirectoryField(10, dir_line, fieldBuffer);
tmp = fieldBuffer;
dir_entry->id = atoi(++tmp);
//--Start-line in par-section
getDirectoryField(2, dir_line, fieldBuffer);
dir_entry->startLine = atol(fieldBuffer);
//--Tranformation matrix id
getDirectoryField(7, dir_line, fieldBuffer);
dir_entry->transfId = atol(fieldBuffer);
//--Status field
getDirectoryField(9, dir_line, fieldBuffer);
dir_entry->status.setValues(fieldBuffer);
// Second directory-entry line
// ===========================
readFileLine(infile, dir_line);
//--Color number
getDirectoryField(3, dir_line, fieldBuffer);
dir_entry->colorNbr = (colorIndices)atoi(fieldBuffer);
//--Number of lines in par-section
getDirectoryField(4, dir_line, fieldBuffer);
dir_entry->nofLines = atoi(fieldBuffer);
//--Form number
getDirectoryField(5, dir_line, fieldBuffer);
dir_entry->formNbr = atoi(fieldBuffer);
//--Check if this entry could be a body
switch (dir_entry->entNbr) {
case 100:
case 102:
case 106:
case 141:
case 142:
case 143:
case 144:
dir_entry->canBeBody = true;
break;
}
return dir_entry;
}
int
InputIges::readDoubleFields(istrstream*& data_line, int nof_fields, double* buffer)
{
//NOTE: we read data-lines until necessary number of
//data fields is read from the file
int counter;
for(counter = 0; counter < nof_fields; counter++) {
getDataField(data_line, dataFieldBuffer);
buffer[counter] = atof(dataFieldBuffer);
}
return counter;
}
int
InputIges::readIntFields(istrstream*& data_line, int nof_fields, int* buffer)
{
//NOTE: we read data-lines until necessary number of
//data fields is read from the file
int counter;
for(counter = 0; counter < nof_fields; counter++) {
getDataField(data_line, dataFieldBuffer);
buffer[counter] = atol(dataFieldBuffer);
}
return counter;
}
// Method reads line body-element.
bool
InputIges::readLine(Body* body)
{
return false;
}
// Method reads a nurbs-spline formed body-element.
bool
InputIges::readNurbs(Body* body)
{
return false;
}
// Method reads one point from input-string *s*.
bool
InputIges::readPoint(istrstream*& data_line, Point3& p)
{
for(int i = 0; i < 3; i++) {
getDataField(data_line, dataFieldBuffer);
p[i] = atof(dataFieldBuffer);
p[i] *= model->unit.conv[i];
}
return true;
}
// Method reads one vertex from input-string *s*.
BodyElement*
InputIges::readVertex(istrstream*& data_line)
{
static Point3 point;
static GcPoint gpoint;
if ( !readPoint(data_line, point) )
return NULL;
gpoint.setPosit(point[0], point[1], point[2]);
// Create vertex from the point in the input file.
BodyElement* vertex = new BodyElement1D(&gpoint);
return vertex;
}
//******************************************
//****** IGES ENTITY READING ROUTINES ******
//******************************************
// Circular arc entity (Type 100)
bool
InputIges::read_100(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
static ecif_EdgeGeometry_X edge;
init_trx_data(edge);
edge.type = ECIF_CIRCLE;
int i,j;
int int_fld;
double dbl_fldb[1];
char chr_fld;
bool is_closed;
static Point3 points[3];
locateParamEntry(de);
//-Read one data-line
readDataLine(lineBuffer, dataBuffer);
istrstream* data_line = new istrstream(dataBuffer);
//-Read center and two points
*data_line >> int_fld >> chr_fld; // Entity-id
readDoubleFields(data_line, 1, dbl_fldb); // z-inclination
for(i = 0; i < 3; i++) {
points[i][2] = 0.0;
for (j = 0; j < 2; j++) {
readDoubleFields(data_line, 1, dbl_fldb);
points[i][j] = dbl_fldb[0];
}
}
if ( isZero(dist3(points[1], points[2])) ) {
is_closed = true;
} else {
is_closed = false;
}
if ( modelDimension == ECIF_2D && is_closed ) {
de->canBeBody = true;
}
if ( check_only_status ) {
return result;
}
// Create body element
// ===================
edge.location = new Point3[1];
edge.start = new Point3[1];
edge.end = new Point3[1];
for (i = 0; i < 3; i++) {
edge.location[0][i] = points[0][i];
edge.start[0][i] = points[1][i];
edge.end[0][i] = points[2][i];
}
int body_layer = 0;
createBodyElement2D(de->body, body_layer, edge);
reset_trx_data(edge);
return result;
}
// Composite curve entity (Type 102)
bool
InputIges::read_102(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int i;
int int_fld, int_fldb[1];
char chr_fld;
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
//-Read number of curves in the composite
int nof_crvs;
*data_line >> int_fld >> chr_fld; // Entry-id
*data_line >> nof_crvs >> chr_fld;
int* crv_id_table = new int[nof_crvs];
IgesDirectoryEntry* comp_de;
//-Read component dir-ids and update the reference
for(i = 0; i < nof_crvs; i++) {
readIntFields(data_line, 1, int_fldb);
crv_id_table[i] = int_fldb[0];
comp_de = getDirectoryEntry(int_fldb[0]);
comp_de->referingId = de->id;
}
delete [] crv_id_table;
return result;
}
// Copious data entity (Type 106)
// Path of data points
bool
InputIges::read_106(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
bool is_closed = ( de->formNbr == 63 );
if ( modelDimension == ECIF_2D && is_closed ) {
de->canBeBody = true;
}
if ( check_only_status ) {
return result;
}
// Read geometry data
// ==================
int i,j;
int int_fld;
char chr_fld;
double dbl_fld[1];
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
//-Read format of points
int read_size;
int point_size;
int point_type;
int nof_points;
double common_z;
*data_line >> int_fld >> chr_fld; // Entry-id
*data_line >> point_type >> chr_fld; // Point type
*data_line >> nof_points >> chr_fld; // Nof tuples
readDoubleFields(data_line, 1, dbl_fld); // Common z coordinate (for type 1 points)
if ( point_type == 1 ) {
point_size = 2;
read_size = 2;
} else if ( point_type == 2 ) {
point_size = 3;
read_size = 3;
} else if ( point_type == 3 ) {
point_size = 6;
read_size = 3;
}
Point3* points = new Point3[nof_points];
//-Read points
int read_count = 0;
for(i = 0; i < nof_points; i++) {
points[i][0] = points[i][1] = points[i][2] = 0.0;
for (j = 0; j < read_size; j++) {
readDoubleFields(data_line, 1, dbl_fld);
read_count++;
// If we are reading relevant point data
if ( read_count <= read_size ) {
points[i][read_count - 1] = dbl_fld[0];
}
// Reset counter if all point data read
read_count = read_count % point_size;
}
}
IgesDirectoryEntry* comp_de;
//-We are reading a surface into a 3D model
if ( modelDimension == ECIF_3D ) {
// body->addElement(from this face-element etc....);
result = false;
}
//-We are reading a body into a 2D model!
else if ( modelDimension == ECIF_2D ) {
int body_layer = 0;
createBodyElement2D(de->body, body_layer, nof_points, points);
}
delete[] points;
return result;
}
// Line entity (Type 110)
bool
InputIges::read_110(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
int i,j;
int int_fld;
char chr_fld;
static Point3 points[2];
locateParamEntry(de);
//-Read one data-line
readDataLine(lineBuffer, dataBuffer);
istrstream* data_line = new istrstream(dataBuffer);
//-Read two points
*data_line >> int_fld >> chr_fld; // Entity-id
for(i = 0; i < 2; i++) {
readPoint(data_line, points[i]);
}
int body_layer = 0;
createBodyElement2D(de->body, body_layer, points[0], points[1]);
return result;
}
// Rational B-spline curve entity (Type 126)
bool
InputIges::read_126(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
static ecif_EdgeGeometry_X edge;
init_trx_data(edge);
locateParamEntry(de);
int i,j, int_fld;
char chr_fld;
//-Read one data-line
readDataLine(lineBuffer, dataBuffer);
istrstream* data_line = new istrstream(dataBuffer);
int nof_cp, nof_kp, degree;
int planar_flg, open_flg, polyn_flg, periodic_flg;
*data_line >> int_fld >> chr_fld; //-Entry-id
*data_line >> nof_cp >> chr_fld; //-Nof control-points - 1
nof_cp += 1;
*data_line >> degree >> chr_fld; //-Degree of basis functions
nof_kp = nof_cp - degree + 1; //-Number of knot-points
nof_kp += 2 * degree; // multiplicity at ends added!!
*data_line >> planar_flg >> chr_fld; //-0= non-planar
*data_line >> open_flg >> chr_fld; //-0= open curve
*data_line >> polyn_flg >> chr_fld; //-0=rational, 1=polynomial
*data_line >> periodic_flg >> chr_fld; //-0=non-periodic
//-Read data into a temporary data-vector
//Data length: (control-points (x,y,z,w)+ knots
int data_len = 4 * nof_cp + nof_kp;
double* crv_data = new double[data_len];
int nof_values = readDoubleFields(data_line, data_len, crv_data);
//-Copy data from crv_data into proper components
double* knots = new double[nof_kp];
Point4* ct_points = new Point4[nof_cp];
int pos = 0;
//-Knot points are first
for(i=0; i < nof_kp; i++)
knots[i] = crv_data[pos++];
//-Then come weights
for(i=0; i < nof_cp; i++) {
ct_points[i][3] = crv_data[pos++];
}
//-Then come control points
edge.start = new Point3[1];
edge.end = new Point3[1];
for(i=0; i < nof_cp; i++) {
for(j=0; j < 3; j++) {
//-First control point is the start-point!
if ( i == 0 ) {
edge.start[0][j] = crv_data[pos];
}
//-Last control point is the end-point!
if ( i == nof_cp - 1 ) {
edge.end[0][j] = crv_data[pos];
}
//NOTE: In Iges points are not in homogenous form
// We must transform them into (xw,yw,zw,w) format
ct_points[i][j] = ct_points[i][3] * crv_data[pos++];
}
}
edge.isRational = (polyn_flg == 0);
edge.degree = degree;
edge.nofKnots = nof_kp;
edge.knots = knots;
edge.nofCpoints = nof_cp;
edge.cpoints = ct_points;
int body_layer = 0;
createBodyElement2D(de->body, body_layer, edge);
delete[] crv_data;
reset_trx_data(edge);
return result;
}
// Rational B-spline surface entity (Type 128)
bool
InputIges::read_128(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int i,j;
int int_fld;
char chr_fld;
//-Read one data-line
readDataLine(lineBuffer, dataBuffer);
istrstream* data_line = new istrstream(dataBuffer);
int nof_cp, polyn_flg;
int nof_cp_u, nof_kp_u, degree_u;
int open_flg_u, periodic_flg_u;
int nof_cp_v, nof_kp_v, degree_v;
int open_flg_v, periodic_flg_v;
*data_line >> int_fld >> chr_fld; //-Entry-id
//---u-parameter
*data_line >> nof_cp_u >> chr_fld; //-Nof control-points - 1
nof_cp_u += 1;
*data_line >> degree_u >> chr_fld; //-Degree of basis functions
nof_kp_u = nof_cp_u - degree_u + 1; //-Number of knot-points
nof_kp_u += 2 * degree_u; // multiplicity at ends added!!
//---v-parameter
*data_line >> nof_cp_v >> chr_fld; //-Nof control-points - 1
nof_cp_v += 1;
*data_line >> degree_v >> chr_fld; //-Degree of basis functions
nof_kp_v = nof_cp_v - degree_v + 1; //-Number of knot-points
nof_kp_v += 2 * degree_v; // multiplicity at ends added!!
//---other parameters
*data_line >> open_flg_u >> chr_fld; //-0= open curve
*data_line >> open_flg_v >> chr_fld; //-0= open curve
*data_line >> polyn_flg >> chr_fld; //-0=rational, 1=polynomial
*data_line >> periodic_flg_u >> chr_fld; //-0=non-periodic
*data_line >> periodic_flg_v >> chr_fld; //-0=non-periodic
//-Read data into a temporary data-vector
//Data length: (control-points (x,y,z,w)+ knots
// total number of control-point (cp_u * cp_v array)
nof_cp = nof_cp_u * nof_cp_v;
int data_len = nof_kp_u + nof_kp_v + 4 * nof_cp ;
double* crv_data = new double[data_len];
int nof_values = readDoubleFields(data_line, data_len, crv_data);
//-Copy data from crv_data into proper components
double* knots_u = new double[nof_kp_u];
double* knots_v = new double[nof_kp_v];
Point4* cpoints = new Point4[nof_cp];
int pos = 0;
//-Knot-u points are first
for(i=0; i < nof_kp_u; i++)
knots_u[i] = crv_data[pos++];
//-Knot-u points are next
for(i=0; i < nof_kp_v; i++)
knots_v[i] = crv_data[pos++];
//-Weights are next
for(i=0; i < nof_cp; i++) {
cpoints[i][3] = crv_data[pos++];
}
//-Control points are next
//NOTE: In Iges points are not in homogenous form
// We must transform them into (xw,yw,zw,w) format
for(i=0; i < nof_cp; i++) {
for(j=0; j < 3; j++)
cpoints[i][j] = cpoints[i][3] * crv_data[pos++];
}
ecif_FaceGeometry_X sP;
sP.isRational = (polyn_flg == 0);
sP.degree_u = degree_u;
sP.degree_v = degree_v;
sP.nofKnots_u = nof_kp_u;
sP.nofKnots_v = nof_kp_v;
sP.knots_u = knots_v;
sP.knots_v = knots_v;
sP.nofCpoints_u = nof_cp_u;
sP.nofCpoints_v = nof_cp_v;
sP.nofCpoints = nof_cp;
sP.cpoints = cpoints;
delete [] crv_data;
//-Create nurbs-curve element
//--Corner points
BodyElement* vertices[4];
int vertex_ids[4];
static GcPoint point;
int corner_ids[4];
corner_ids[0] = 0;
corner_ids[1] = nof_cp_u - 1;
corner_ids[2] = (nof_cp_u - 1) * nof_cp_v;
corner_ids[3] = nof_cp_u * nof_cp_v - 1;
// Create model vertex elements from nurbs corner points
for (i = 0; i < 4; i++) {
int c_id = corner_ids[i];
double w = sP.cpoints[c_id][3];
point.setPos(X, sP.cpoints[c_id][0]/w);
point.setPos(Y, sP.cpoints[c_id][1]/w);
point.setPos(Z, sP.cpoints[c_id][2]/w);
vertices[i] = new BodyElement1D(&point);
vertex_ids[i] = vertices[i]->Id();
model->addBodyElement(vertices[i]);
}
// Create a new element into the 3D-body
BodyElement* body_elm = new BodyElement3D(4, vertex_ids, &sP);
de->body->addElement(0, body_elm);
model->addBodyElement(body_elm);
return result;
}
// Boundary entity (Type 141)
// This entry point to a untrimmed surface and to all curve elements
// which define this surface as boundaries.
bool
InputIges::read_141(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int i, j;
int int_fld, int_fldb[1];
char chr_fld;
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
//-Skip 4 (nbr sep) pairs:
// Entry id
// Type of srf representation (0=in trimmimg space, 1=in model space)
// Preferred representation (0=unspec., 1=model space, 2=param. spcace, 3=equal)
// Pointer to the DE of the untrimmed surface
for(i = 0; i < 4; i++) {
*data_line >> int_fld >> chr_fld;
}
//-Read number of curves in the boundary
int nof_crvs;
*data_line >> nof_crvs >> chr_fld;
int* crv_id_table = new int[nof_crvs];
IgesDirectoryEntry* comp_de;
//-Read component ids and update references
for(i = 0; i < nof_crvs; i++) {
for(j = 0; j < 4; j++) {
readIntFields(data_line, 1, int_fldb);
if (j == 0) {
crv_id_table[i] = int_fldb[0];
comp_de = getDirectoryEntry(int_fldb[0]);
comp_de->referingId = de->id;
}
}
}
delete [] crv_id_table;
return result;
}
// Curve on a parametric surface entity (Type 142)
bool
InputIges::read_142(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int int_fld;
char chr_fld;
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
int prmc_entry;
int srf_entry;
int srfc_entry;
*data_line >> int_fld >> chr_fld; //-Entry-number
*data_line >> int_fld >> chr_fld; //-Type of the curve
*data_line >> srf_entry >> chr_fld; //-Pointer to surface
*data_line >> prmc_entry >> chr_fld; //-Pointer to crv in param space
*data_line >> srfc_entry >> chr_fld; //-Pointer to crv on the surface
*data_line >> int_fld >> chr_fld; //-Preferred format
// Update reference to the component
IgesDirectoryEntry* comp_de = getDirectoryEntry(srfc_entry);
comp_de->referingId = de->id;
return result;
}
// This entry defines a bounded surface entity (Type 143)
// It points to the surface and to the entry which defines the
// bounding curves (fex. to an entry 141)
bool
InputIges::read_143(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int i;
int int_fld;
char chr_fld;
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
int nof_srfs, nof_bnds, nof_values;
*data_line >> int_fld >> chr_fld; // entry-number
*data_line >> nof_srfs >> chr_fld; // Nof surface entities
int* srf_id_table = new int[nof_srfs];
nof_values = readIntFields(data_line, nof_srfs, srf_id_table);
*data_line >> nof_bnds >> chr_fld; // Nof boundary entities
int* bnd_id_table = new int[nof_bnds];
nof_values = readIntFields(data_line, nof_bnds, bnd_id_table);
IgesDirectoryEntry* comp_de;
int nof_refs;
int* refs_table;
// In 2D boundaries
if ( modelDimension == ECIF_2D ) {
nof_refs = nof_bnds;
refs_table = bnd_id_table;
// In 3D surfaces
} else {
nof_refs = nof_srfs;
refs_table = srf_id_table;
}
for(i = 0; i < nof_refs; i++) {
comp_de = getDirectoryEntry(refs_table[i]);
comp_de->referingId = de->id;
}
delete [] bnd_id_table;
delete [] srf_id_table;
return result;
}
// Trimmed (parametric) surface entity (Type 144)
bool
InputIges::read_144(IgesDirectoryEntry* de, bool check_only_status)
{
bool result = true;
locateParamEntry(de);
int i;
int int_fld, int_fldb[1];
char chr_fld;
istrstream* data_line;
readDataLine(lineBuffer, dataBuffer);
data_line = new istrstream(dataBuffer);
int srf_entry;
int obnd_entry;
int nof_ibnds;
*data_line >> int_fld >> chr_fld; //-Entry-number
*data_line >> srf_entry >> chr_fld; //-Pointer to surface
*data_line >> int_fld >> chr_fld; //-Type of bounded surface
// 0=the outer bndr is the bndr of D
// 1=otherwise
*data_line >> nof_ibnds >> chr_fld; //-Nof inner bndrs defined by simple closed curves
*data_line >> obnd_entry >> chr_fld; //-Pointer to outer bndr of the surface
// defining the inner bndr of the srf.
IgesDirectoryEntry* comp_de;
//-Read outer boundary on the surface (if defined!)
if (obnd_entry > 0) {
comp_de = getDirectoryEntry(obnd_entry);
comp_de->referingId = de->id;
}
//-Read inner boundary defining curves (if defined!)
if (nof_ibnds > 0) {
int* bnd_id_table = new int[nof_ibnds];
int ibnd_entry;
//-Read component row-ids and corresponding data-rows
for(i = 0; i < nof_ibnds; i++) {
readIntFields(data_line, 1, int_fldb);
bnd_id_table[i] = int_fldb[0];
comp_de = getDirectoryEntry(int_fldb[0]);
comp_de->referingId = de->id;
}
delete [] bnd_id_table;
}
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1