/* sort_form - sort fields on form(per page) */ static void sort_form(FORM *f) { FIELD **field; FIELD *p; int i, page, pmin, pmax; field = f->field; for (page = 0; page < f->maxpage; ++page) { /* for each page */ p = (FIELD *) 0; pmin = Pmin(f, page); pmax = Pmax(f, page); for (i = pmin; i <= pmax; ++i) { /* for each field */ field[i]->index = i; field[i]->page = page; p = insert(field[i], p); } Smin(f, page) = p->index; /* set sorted min */ Smax(f, page) = p->sprev->index; /* set sorted max */ } }
double SceneGL::SetCameraDefaultPosition(const NeighborMesh& mesh) { //roughly adjust view frustrum to object and camera position Vector3d Pmin(mesh.vertices[0]), Pmax(mesh.vertices[0]); Vector3d Center(0,0,0); for( int i=0; i< mesh.vertices.size(); i++) { Vector3d P(mesh.vertices[i]); for( int j=0; j<2; j++) { Pmin[j] = min(Pmin[j],P[j]); Pmax[j] = max(Pmax[j],P[j]); } Center += P; } Center/= mesh.vertices.size(); target = Center; //length of the diagonal of the bouding box double distance = (Pmax-Pmin).norm(); //set arbitraty position to camera and adjusts max and min view planes position = target + Vector3d( 0,0, distance*3); znear = distance*0.1; zfar = distance*5; return distance; }
CC_FILE_ERROR ShpFilter::loadFile(QString filename, ccHObject& container, LoadParameters& parameters) { QFile file(filename); if (!file.open(QIODevice::ReadOnly)) return CC_FERR_READING; //global shift CCVector3d Pshift(0,0,0); //read header (refer to ESRI Shapefile Technical Description) if (file.size() < 100) return CC_FERR_MALFORMED_FILE; char header[100]; file.read(header,100); int32_t fileLength = 0; { /*** WARNING: the beginning of the header is written with big endianness! ***/ const char* _header = header; //Byte 0: SHP code const int32_t code = qFromBigEndian<int32_t>(*reinterpret_cast<const int32_t*>(_header)); if (code != 9994) { return CC_FERR_MALFORMED_FILE; } _header += 4; //Byte 4: unused (20 bytes) _header += 20; //Byte 24: file length (will be written... later ;) fileLength = qFromBigEndian<int32_t>(*reinterpret_cast<const int32_t*>(_header)); fileLength *= 2; //fileLength is measured in 16-bit words _header += 4; /*** WARNING: from now on, we only read data with little endianness! ***/ //Byte 28: file verion const int32_t version = qFromLittleEndian<int32_t>(*reinterpret_cast<const int32_t*>(_header)); _header += 4; //Byte 32: shape type int32_t shapeTypeInt = qFromLittleEndian<int32_t>(*reinterpret_cast<const int32_t*>(_header)); _header += 4; ccLog::Print(QString("[SHP] Version: %1 - type: %2").arg(version).arg(ToString(static_cast<ESRI_SHAPE_TYPE>(shapeTypeInt)))); //X and Y bounaries //Byte 36: box X min double xMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Byte 44: box Y min double xMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Byte 52: box X max double yMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Byte 60: box Y max double yMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Z bounaries //Unused, with value 0.0, if not Measured or Z type //Byte 68: box Z min double zMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Byte 76: box Z max double zMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; CCVector3d Pmin(xMin,yMin,zMin); if (HandleGlobalShift(Pmin,Pshift,parameters)) { ccLog::Warning("[SHP] Entities will be recentered! Translation: (%.2f,%.2f,%.2f)",Pshift.x,Pshift.y,Pshift.z); } //M bounaries (M = measures) //Byte 84: M min double mMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; //Byte 92: M max double mMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header)); _header += 8; } assert(fileLength >= 100); if (fileLength < 100) { assert(false); return CC_FERR_MALFORMED_FILE; } fileLength -= 100; if (fileLength == 0) { return CC_FERR_NO_LOAD; } //load shapes CC_FILE_ERROR error = CC_FERR_NO_ERROR; ccPointCloud* singlePoints = 0; qint64 pos = file.pos(); while (fileLength >= 12) { file.seek(pos); assert(pos + fileLength == file.size()); //load shape record in main SHP file { file.read(header,8); //Byte 0: Record Number int32_t recordNumber = qFromBigEndian<int32_t>(*reinterpret_cast<const int32_t*>(header)); //Record numbers begin at 1 //Byte 4: Content Length int32_t recordSize = qFromBigEndian<int32_t>(*reinterpret_cast<const int32_t*>(header+4)); //Record numbers begin at 1 recordSize *= 2; //recordSize is measured in 16-bit words fileLength -= 8; pos += 8; if (fileLength < recordSize) { assert(false); error = CC_FERR_MALFORMED_FILE; break; } fileLength -= recordSize; pos += recordSize; //Record start (byte 0): Shape Type if (recordSize < 4) { assert(false); error = CC_FERR_MALFORMED_FILE; break; } file.read(header,4); recordSize -= 4; int32_t shapeTypeInt = qToLittleEndian<int32_t>(*reinterpret_cast<const int32_t*>(header)); ccLog::Print(QString("[SHP] Record #%1 - type: %2 (%3 bytes)").arg(recordNumber).arg(ToString(static_cast<ESRI_SHAPE_TYPE>(shapeTypeInt))).arg(recordSize)); switch (shapeTypeInt) { case SHP_POLYLINE: case SHP_POLYLINE_Z: case SHP_POLYGON: case SHP_POLYGON_Z: error = LoadPolyline(file,container,recordNumber,static_cast<ESRI_SHAPE_TYPE>(shapeTypeInt),Pshift); break; case SHP_MULTI_POINT: case SHP_MULTI_POINT_Z: case SHP_MULTI_POINT_M: error = LoadCloud(file,container,recordNumber,static_cast<ESRI_SHAPE_TYPE>(shapeTypeInt),Pshift); break; case SHP_POINT: case SHP_POINT_Z: case SHP_POINT_M: error = LoadSinglePoint(file,singlePoints,static_cast<ESRI_SHAPE_TYPE>(shapeTypeInt),Pshift); break; //case SHP_MULTI_PATCH: // error = LoadMesh(file,recordSize); // break; case SHP_NULL_SHAPE: //ignored break; default: //unhandled entity ccLog::Warning("[SHP] Unhandled type!"); break; } } if (error != CC_FERR_NO_ERROR) break; } if (singlePoints) { if (singlePoints->size() == 0) { delete singlePoints; singlePoints = 0; } else { CCLib::ScalarField* sf = singlePoints->getScalarField(0); if (sf) { sf->computeMinAndMax(); singlePoints->showSF(true); } container.addChild(singlePoints); } } return error; }