/*********************************************************************** * * 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_inputIdeasWF.cpp Language: C++ Date: 01.10.98 Version: 1.00 Author(s): Martti Verho Revisions: Abstract: Implementation for Ideas WireFrame bodies ************************************************************************/ #include "ecif_body2D.h" #include "ecif_body3D.h" #include "ecif_bodyElement2D.h" #include "ecif_bodyElement3D.h" #include "ecif_geometry.h" #include "ecif_inputIdeasWF.h" #include "ecif_model.h" extern char read_buffer[]; //*** Constants for reading Ideas data in Nurbs-Format. // Number of data-items (points) per line in the input file. const int NF_COLS = 3; // Length of nurbs-description vector. const int NF_SIZE = 12; // Indecies in the nurbs-description vector (0 - NF_SIZE-1) const int NFI_N = 0; // Number of control-points. const int NFI_NK = 1; // Number of knot-points (N+K). const int NFI_K = 3; // Order of basis. const int NFI_LEN = 10; // Length of curve's control data. const int NFI_DIM = 11; // Dimension (of control points) (2-4). InputIdeasWF::InputIdeasWF(enum ecif_modelDimension m_dim, ifstream& in_file, char* in_filename): InputIdeas(m_dim, in_file, in_filename) { modelDimension = inputDimension; } //***Read all wireframe bodies from a Ideas univ. file dataset (in fact a 2D case!!) bool InputIdeasWF::readCadGeometry() { while (!infile.eof()) { // Read all bodies. int status = readWireFrameBody(); // If end-of-dataset was encountered. if (status == -1) break; } return true; } // Method reads body-name from Ideas univ. file char* InputIdeasWF::readBodyName(char* s) { int dummy; char* name = new char[MAXBODYNAME+1]; char* cptr; istrstream strline(s); // Body 'name' is field-4 (simply color code) strline >> dummy >> dummy >> dummy; cptr = name; int i = 0; char c; // Trim left all blanks while (strline.get() == ' '); // read all non-blanks into name while (((c = strline.get()) != ' ') && (i < MAXBODYNAME)) { *cptr = c; cptr++; i++; } *cptr = '\0'; return name; } // Method reads body-nbr from Ideas univ. file int InputIdeasWF::readBodyNbr(char* s) { int dummy; int nbr; istrstream strline(s); // Body nbr is field-4 (color code) strline >> dummy >> dummy >> dummy >> nbr; return nbr; } // Method reads curve-type info from Ideas univ. file (801) ecif_geometryType InputIdeasWF::readGeomType(char* s) { ecif_geometryType g_type = ECIF_LINE; int dummy; int cnstr_flag; int nurbs_flag; istrstream strline(s); // Points/constraints-exist flag is field-3 (0=no, 1=yes). strline >> dummy >> dummy >> cnstr_flag; // Nurbs-format flag is field-5 (0=no, 1=yes) strline >> dummy >> nurbs_flag; if (nurbs_flag == 1) g_type = ECIF_NURBS; return g_type; } // Method reads a line-segment-element from Ideas univ. file (801) bool InputIdeasWF::readLine(Body* body, char* buffer) { static Point3 p1, p2; // First read Record-3 away. // (it is : 1 1 and doesn't contain useful info) readFileLine(infile, buffer); // Next read the two vertices from infile. // -first vertex-point readFileLine(infile,buffer); readPoint(buffer, p1); // -second vertex-point readFileLine(infile,buffer); readPoint(buffer, p2); int body_layer = 0; // Create a new 2D element into the body createBodyElement2D(body, body_layer, p1, p2); return true; } // Method reads a spline-segment-element in nurbs-form from Ideas univ. file (801) bool InputIdeasWF::readNurbs(Body* body, char* buffer) { static ecif_EdgeGeometry_X edge; init_trx_data(edge); int i,j,pos; // *** Control-point section. int nf_vec[NF_SIZE]; // Read curve-desrcribing vector. readFileLine(infile, buffer); istrstream strline(buffer); for (i = 0; i < NF_SIZE; i++) { strline >> nf_vec[i]; } // Pick curve-defining factors from nf-vector. int nf_dim = nf_vec[NFI_DIM]; // Dimension of control-points. int nf_len = nf_vec[NFI_LEN]; // Length of data. int nf_n = nf_vec[NFI_N]; // Nof control points. int nf_nk = nf_vec[NFI_NK]; // Nof knot points. int nf_k = nf_vec[NFI_K]; // Order of basis. // Read nurbs-curve defining data into a temporary data-vector. double* ct_data = new double[nf_len]; // a temporary data vector. int nf_rows; // nof data-rows in this section. if ( NF_COLS > 0 ) nf_rows = nf_len / NF_COLS; else nf_rows = nf_len; pos = 0; for (i = 0; i < nf_rows; i++) { readFileLine(infile, buffer); istrstream strline(buffer); for (j = 0; j < NF_COLS; j++) { strline >> ct_data[pos++]; } } // Now create final data-structures for nurbs-curve and // read them from temporary data-vector *ct_data*. // *** Control points (at the beginning of the data) Point4* ct_points = new Point4[nf_n]; pos = 0; for (i = 0; i < nf_n; i++) { //We use always 4D-points int pos = 4 * i; ct_points[i][0] = 0.0; ct_points[i][1] = 0.0; ct_points[i][2] = 0.0; ct_points[i][3] = 1.0; for (j = 0; j < nf_dim; j++) { //Note: coordinates are scaled by unit ct_points[i][j] = model->unit.conv[j] * ct_data[pos++]; } } // *** Next come knot-points double* knots = new double[nf_nk]; pos = nf_n * nf_dim; for (i = 0; i < nf_nk; i++) { knots[i] = ct_data[pos + i]; } //---Create a nurbs-curve body-element //-Two vertices // first vertex from the first control-point // second vertex from the last control-point edge.start = new Point3[1]; edge.end = new Point3[1]; for (i = 0; i < 3; i++) { edge.start[0][i] = ct_points[0][i] / ct_points[0][3]; edge.end[0][i] = ct_points[nf_n - 1][i] / ct_points[nf_n - 1][3]; } //-Other parameters edge.type = ECIF_NURBS; edge.isRational = (nf_dim == 4); // Is this ok !!!###!!! edge.degree = nf_k - 1; edge.nofKnots = nf_nk; edge.nofCpoints = nf_n; edge.knots = knots; edge.cpoints = ct_points; //-Create a new 2D element into the body int body_layer = 0; createBodyElement2D(body, body_layer, edge); // *** Defining points section. // Read nof defining point // NOT IN USE in practice. Used only to read 'off' the data from file !!!***!!! int df_n; readFileLine(infile, buffer); strline >> df_n; // Read defining-points desrcibing vector. All data on a single line. // This is a table where there are three items per defining-point: // 1. curve passes through point flag (0=no, 1=yes). // 2. tangent/derivative vector specified (0=no, 1=tangent, 2=derivative). // 3. curvature specified (0=no, 1=yes). readFileLine(infile, buffer); // Jump to the end of defining points section. readFileLine(infile, buffer, df_n); reset_trx_data(edge); return true; } // Method reads one wireframe body-element from Ideas univ. file dataset // and adds body-element into body/model. // Returns: 1=new body was created, 0=old body was updateds, -1 = end-of-odataset. int InputIdeasWF::readWireFrameBody() { Body* body; // We want to start from this position, when the body-read loop is started! //streampos cur_pos = infile.tellg(); // =====Read body ID, CODE and NAME (from color code!) ( Record-1). readFileLine(infile, read_buffer); // However, check first that ***end-of-datset*** (-1) is not encountered // In this case dataset is empty! if (endofDataset(read_buffer)) return -1; // Now read id, code and name. //char* name = readBodyName(read_buffer); int id_nbr = readBodyNbr(read_buffer); char* name = NULL; // =====Read CURVE-TYPE information ( Record-2). readFileLine(infile, read_buffer); ecif_geometryType g_type = readGeomType(read_buffer); // Back to body's starting position! //infile.seekg(cur_pos); // We check if we are reading new pieces for an old body! // Checking is based on a *local table* where we have id-numbers // from the file (id_nbr) and system (automagically) generated // technical id-numbers (body->Tag()) as pairs. bool isNewBody = false; IdNumberTable::iterator itr = bodyNumbers.find(id_nbr); // Old body if (itr != bodyNumbers.end()) body = model->getBodyByTag((*itr).second); // Create a new body else { colorIndices color = (colorIndices)id_nbr; // id_nbr is read from color code! //2D geometry if (modelDimension == ECIF_2D) body = new Body2D(GEOM_BODY, id_nbr, name, color); //3D geometry else if (modelDimension == ECIF_3D) body = new Body3D(GEOM_BODY, id_nbr, name, color); model->addBody(body); isNewBody = true; bodyNumbers[id_nbr] = body->Tag(); } // How to read depends on the geometry-type: switch (g_type) { case ECIF_LINE: readLine(body, read_buffer); break; case ECIF_NURBS: readNurbs(body, read_buffer); break; default: break; } if (isNewBody) return 1; else return 0; }