mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-05 23:41:44 +00:00
IfcParse: allow reading of IFC file from stdin
IfcServer: first commit of a stdin/stdout interface to IfcGeomObjects [undocumented for now] BIMserver_plugin: first commit of IfcEngine plugin implementation for use with http://BIMserver.org [undocumented for now]
This commit is contained in:
@@ -58,7 +58,9 @@ CHECK_ADD_OCE_OCC_DEF(iomanip.h)
|
||||
CHECK_ADD_OCE_OCC_DEF(iostream)
|
||||
CHECK_ADD_OCE_OCC_DEF(iostream.h)
|
||||
|
||||
ADD_DEFINITIONS(-O2)
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
|
||||
INCLUDE_DIRECTORIES(${OCC_INCLUDE_DIR})
|
||||
|
||||
@@ -275,6 +275,24 @@ extern bool IfcGeomObjects::Init(const char* fn, bool world_coords, std::ostream
|
||||
total = shapereps->Size();
|
||||
return true;
|
||||
}
|
||||
extern bool IfcGeomObjects::Init(std::istream& f, int len, bool world_coords, std::ostream* log1, std::ostream* log2) {
|
||||
if ( log1 || log2 ) Ifc::SetOutput(log1,log2);
|
||||
use_world_coords = world_coords;
|
||||
if ( !Ifc::Init(f, len) ) return false;
|
||||
|
||||
shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
|
||||
if ( ! shapereps ) return false;
|
||||
|
||||
outer = shapereps->begin();
|
||||
entities.reset();
|
||||
currentGeomObj = _get();
|
||||
|
||||
if ( ! currentGeomObj ) return false;
|
||||
|
||||
done = 0;
|
||||
total = shapereps->Size();
|
||||
return true;
|
||||
}
|
||||
extern int IfcGeomObjects::Progress() {
|
||||
return 100 * done / total;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace IfcGeomObjects {
|
||||
};
|
||||
|
||||
extern bool Init(const char* fn, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
extern bool Init(std::istream& f, int len, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
extern const IfcGeomObject* Get();
|
||||
extern bool Next();
|
||||
extern int Progress();
|
||||
|
||||
@@ -39,6 +39,7 @@ File::File(const std::string& fn) {
|
||||
stream.seekg(0,std::ios_base::end);
|
||||
size = (unsigned int) stream.tellg();
|
||||
stream.seekg(0,std::ios_base::beg);
|
||||
paging = size > BUF_SIZE;
|
||||
buffer = new char[size < BUF_SIZE ? size : BUF_SIZE];
|
||||
ptr = 0;
|
||||
len = 0;
|
||||
@@ -46,6 +47,18 @@ File::File(const std::string& fn) {
|
||||
ReadBuffer(false);
|
||||
}
|
||||
|
||||
File::File(std::istream& f, int l) {
|
||||
eof = false;
|
||||
size = l;
|
||||
paging = false;
|
||||
buffer = new char[size];
|
||||
f.read(buffer,size);
|
||||
valid = f.gcount() == size;
|
||||
ptr = 0;
|
||||
len = l;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
void File::Close() {
|
||||
stream.close();
|
||||
delete[] buffer;
|
||||
@@ -71,7 +84,10 @@ void File::ReadBuffer(bool inc) {
|
||||
// Seeks an arbitrary position in the file
|
||||
//
|
||||
void File::Seek(unsigned int o) {
|
||||
if ( o >= offset && (o < (offset+len)) ) {
|
||||
if ( !paging ) {
|
||||
ptr = o;
|
||||
eof = false;
|
||||
} else if ( o >= offset && (o < (offset+len)) ) {
|
||||
ptr = o - offset;
|
||||
} else {
|
||||
offset = o;
|
||||
@@ -92,7 +108,9 @@ char File::Peek() {
|
||||
// Returns the character at specified offset
|
||||
//
|
||||
char File::Read(unsigned int o) {
|
||||
if ( o >= offset && (o < (offset+len)) ) {
|
||||
if ( ! paging ) {
|
||||
return buffer[o];
|
||||
} else if ( o >= offset && (o < (offset+len)) ) {
|
||||
return buffer[o-offset];
|
||||
} else {
|
||||
stream.clear();
|
||||
@@ -112,7 +130,10 @@ unsigned int File::Tell() {
|
||||
// Increments cursor and reads new chunk if necessary
|
||||
//
|
||||
void File::Inc() {
|
||||
if ( ++ptr == len ) { ReadBuffer(); }
|
||||
if ( ++ptr == len ) {
|
||||
if ( paging ) ReadBuffer();
|
||||
else eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
Tokens::Tokens(IfcParse::File *f) {
|
||||
@@ -433,6 +454,7 @@ void Entity::Load(std::vector<unsigned int>& ids, bool seek) {
|
||||
if ( seek ) {
|
||||
Ifc::file->Seek(offset);
|
||||
Token datatype = Ifc::tokens->Next();
|
||||
std::string dt = TokenFunc::toString(datatype);
|
||||
if ( ! TokenFunc::isDatatype(datatype)) throw IfcException("Unexpected token while parsing entity");
|
||||
_type = Ifc2x3::Type::FromString(TokenFunc::asString(datatype));
|
||||
}
|
||||
@@ -502,7 +524,13 @@ unsigned int Entity::id() { return _id; }
|
||||
// Gets the unit definitins from the file
|
||||
//
|
||||
bool Ifc::Init(const std::string& fn) {
|
||||
file = new File (fn);
|
||||
return Ifc::Init(new File(fn));
|
||||
}
|
||||
bool Ifc::Init(std::istream& f, int len) {
|
||||
return Ifc::Init(new File(f,len));
|
||||
}
|
||||
bool Ifc::Init(IfcParse::File* f) {
|
||||
file = f;
|
||||
if ( ! file->valid ) return false;
|
||||
tokens = new Tokens (file);
|
||||
Token token = 0;
|
||||
@@ -545,9 +573,14 @@ bool Ifc::Init(const std::string& fn) {
|
||||
}
|
||||
|
||||
if ( log1 ) std::cout << "\rDone scanning file " << std::endl;
|
||||
|
||||
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *EntitiesByType<Ifc2x3::IfcUnitAssignment>()->begin();
|
||||
IfcUtil::IfcAbstractSelect::list units = unit_assignment->Units();
|
||||
|
||||
Ifc2x3::IfcUnitAssignment::list unit_assignments = EntitiesByType<Ifc2x3::IfcUnitAssignment>();
|
||||
IfcUtil::IfcAbstractSelect::list units = IfcUtil::IfcAbstractSelect::list();
|
||||
if ( unit_assignments->Size() ) {
|
||||
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *unit_assignments->begin();
|
||||
IfcUtil::IfcAbstractSelect::list units = unit_assignment->Units();
|
||||
}
|
||||
if ( units )
|
||||
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
|
||||
const IfcUtil::IfcAbstractSelect::ptr base = *it;
|
||||
Ifc2x3::IfcSIUnit::ptr unit = Ifc2x3::IfcSIUnit::ptr();
|
||||
|
||||
@@ -61,11 +61,13 @@ namespace IfcParse {
|
||||
unsigned int len;
|
||||
unsigned int offset;
|
||||
void ReadBuffer(bool inc=true);
|
||||
bool paging;
|
||||
public:
|
||||
bool valid;
|
||||
bool eof;
|
||||
unsigned int size;
|
||||
File(const std::string& fn);
|
||||
File(std::istream& f, int len);
|
||||
char Peek();
|
||||
char Read(unsigned int offset);
|
||||
void Inc();
|
||||
@@ -258,9 +260,10 @@ public:
|
||||
template <class T>
|
||||
static typename T::list EntitiesByType() {
|
||||
IfcEntities e = EntitiesByType(T::Class());
|
||||
typename T::list l ( new IfcTemplatedEntityList<T>() ); \
|
||||
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \
|
||||
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));\
|
||||
typename T::list l ( new IfcTemplatedEntityList<T>() );
|
||||
if ( e && e->Size() )
|
||||
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
|
||||
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
@@ -268,6 +271,8 @@ public:
|
||||
static IfcEntities EntitiesByReference(int id);
|
||||
static IfcEntity EntityById(int id);
|
||||
static bool Init(const std::string& fn);
|
||||
static bool Init(std::istream& fn, int len);
|
||||
static bool Init(IfcParse::File* f);
|
||||
static void Dispose();
|
||||
static float LengthUnit;
|
||||
static float PlaneAngleUnit;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This examples exposes the IfcOpenShell API through a command-based stdin *
|
||||
* interface *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../ifcparse/IfcGeomObjects.h"
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
int main ( int argc, char** argv ) {
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
std::cout.setf(std::ios_base::binary);
|
||||
#endif
|
||||
bool has_more = false;
|
||||
std::cout.write("IfcOpenShell-0.2.0",18);
|
||||
std::cout.flush();
|
||||
const IfcGeomObjects::IfcGeomObject* ifc_geom = 0;
|
||||
while (1) {
|
||||
std::string command;
|
||||
std::cin >> command;
|
||||
if ( command == "load" ) {
|
||||
std::string fn;
|
||||
std::getline(std::cin,fn);
|
||||
fn = fn.erase(0,fn.find_first_not_of(" "));
|
||||
has_more = IfcGeomObjects::Init(fn.c_str(),true,0,&std::cerr);
|
||||
std::cout.write(has_more ? "y" : "n",1);
|
||||
std::cout.flush();
|
||||
} else if ( command == "loadstdin" ) {
|
||||
std::cout << "ok" << std::flush;
|
||||
int len;
|
||||
std::cin >> len;
|
||||
std::cout << "ok" << std::flush;
|
||||
has_more = IfcGeomObjects::Init(std::cin,len,true,0,&std::cerr);
|
||||
std::cout.write(has_more ? "y" : "n",1);
|
||||
std::cout.flush();
|
||||
} else if ( command == "get" ) {
|
||||
if ( !has_more ) {
|
||||
std::cout << "Not loaded" << std::flush;
|
||||
} else {
|
||||
ifc_geom = IfcGeomObjects::Get();
|
||||
const int vcount = ifc_geom->mesh->verts.size() / 3;
|
||||
std::cout.write((char*)&vcount,sizeof(int));
|
||||
std::cout.write((char*)&ifc_geom->mesh->verts[0],sizeof(float)*vcount*3);
|
||||
const int fcount = ifc_geom->mesh->faces.size() / 3;
|
||||
std::cout.write((char*)&fcount,sizeof(int));
|
||||
std::cout.write((char*)&ifc_geom->mesh->faces[0],sizeof(int)*fcount*3);
|
||||
std::cout.flush();
|
||||
}
|
||||
} else if ( command == "type" ) {
|
||||
if ( ! ifc_geom ) {
|
||||
std::cout << "Not loaded" << std::flush;
|
||||
} else {
|
||||
std::cout << ifc_geom->type << std::flush;
|
||||
}
|
||||
} else if ( command == "guid" ) {
|
||||
if ( ! ifc_geom ) {
|
||||
std::cout << "Not loaded" << std::flush;
|
||||
} else {
|
||||
std::cout << ifc_geom->name << std::flush;
|
||||
}
|
||||
} else if ( command == "next" ) {
|
||||
if ( !has_more ) {
|
||||
std::cout << "Not loaded" << std::flush;
|
||||
} else {
|
||||
has_more = IfcGeomObjects::Next();
|
||||
std::cout.write(has_more ? "y" : "n",1);
|
||||
std::cout.flush();
|
||||
}
|
||||
} else if ( command == "quit" || command == "exit" ) {
|
||||
std::cout << "Bye" << std::flush;
|
||||
break;
|
||||
} else {
|
||||
std::cout << "Unknown command " << command << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user