Skip to content

Commit 0b45066

Browse files
committed
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]
1 parent 086d314 commit 0b45066

6 files changed

Lines changed: 173 additions & 11 deletions

File tree

cmake/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ CHECK_ADD_OCE_OCC_DEF(iomanip.h)
5858
CHECK_ADD_OCE_OCC_DEF(iostream)
5959
CHECK_ADD_OCE_OCC_DEF(iostream.h)
6060

61-
ADD_DEFINITIONS(-O2)
61+
IF(NOT CMAKE_BUILD_TYPE)
62+
SET(CMAKE_BUILD_TYPE "Release")
63+
ENDIF(NOT CMAKE_BUILD_TYPE)
6264
ADD_DEFINITIONS(-fPIC)
6365

6466
INCLUDE_DIRECTORIES(${OCC_INCLUDE_DIR})

src/ifcparse/IfcGeomObjects.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,24 @@ extern bool IfcGeomObjects::Init(const char* fn, bool world_coords, std::ostream
275275
total = shapereps->Size();
276276
return true;
277277
}
278+
extern bool IfcGeomObjects::Init(std::istream& f, int len, bool world_coords, std::ostream* log1, std::ostream* log2) {
279+
if ( log1 || log2 ) Ifc::SetOutput(log1,log2);
280+
use_world_coords = world_coords;
281+
if ( !Ifc::Init(f, len) ) return false;
282+
283+
shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
284+
if ( ! shapereps ) return false;
285+
286+
outer = shapereps->begin();
287+
entities.reset();
288+
currentGeomObj = _get();
289+
290+
if ( ! currentGeomObj ) return false;
291+
292+
done = 0;
293+
total = shapereps->Size();
294+
return true;
295+
}
278296
extern int IfcGeomObjects::Progress() {
279297
return 100 * done / total;
280298
}

src/ifcparse/IfcGeomObjects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ namespace IfcGeomObjects {
9898
};
9999

100100
extern bool Init(const char* fn, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
101+
extern bool Init(std::istream& f, int len, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
101102
extern const IfcGeomObject* Get();
102103
extern bool Next();
103104
extern int Progress();

src/ifcparse/IfcParse.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,26 @@ File::File(const std::string& fn) {
3939
stream.seekg(0,std::ios_base::end);
4040
size = (unsigned int) stream.tellg();
4141
stream.seekg(0,std::ios_base::beg);
42+
paging = size > BUF_SIZE;
4243
buffer = new char[size < BUF_SIZE ? size : BUF_SIZE];
4344
ptr = 0;
4445
len = 0;
4546
offset = 0;
4647
ReadBuffer(false);
4748
}
4849

50+
File::File(std::istream& f, int l) {
51+
eof = false;
52+
size = l;
53+
paging = false;
54+
buffer = new char[size];
55+
f.read(buffer,size);
56+
valid = f.gcount() == size;
57+
ptr = 0;
58+
len = l;
59+
offset = 0;
60+
}
61+
4962
void File::Close() {
5063
stream.close();
5164
delete[] buffer;
@@ -71,7 +84,10 @@ void File::ReadBuffer(bool inc) {
7184
// Seeks an arbitrary position in the file
7285
//
7386
void File::Seek(unsigned int o) {
74-
if ( o >= offset && (o < (offset+len)) ) {
87+
if ( !paging ) {
88+
ptr = o;
89+
eof = false;
90+
} else if ( o >= offset && (o < (offset+len)) ) {
7591
ptr = o - offset;
7692
} else {
7793
offset = o;
@@ -92,7 +108,9 @@ char File::Peek() {
92108
// Returns the character at specified offset
93109
//
94110
char File::Read(unsigned int o) {
95-
if ( o >= offset && (o < (offset+len)) ) {
111+
if ( ! paging ) {
112+
return buffer[o];
113+
} else if ( o >= offset && (o < (offset+len)) ) {
96114
return buffer[o-offset];
97115
} else {
98116
stream.clear();
@@ -112,7 +130,10 @@ unsigned int File::Tell() {
112130
// Increments cursor and reads new chunk if necessary
113131
//
114132
void File::Inc() {
115-
if ( ++ptr == len ) { ReadBuffer(); }
133+
if ( ++ptr == len ) {
134+
if ( paging ) ReadBuffer();
135+
else eof = true;
136+
}
116137
}
117138

118139
Tokens::Tokens(IfcParse::File *f) {
@@ -433,6 +454,7 @@ void Entity::Load(std::vector<unsigned int>& ids, bool seek) {
433454
if ( seek ) {
434455
Ifc::file->Seek(offset);
435456
Token datatype = Ifc::tokens->Next();
457+
std::string dt = TokenFunc::toString(datatype);
436458
if ( ! TokenFunc::isDatatype(datatype)) throw IfcException("Unexpected token while parsing entity");
437459
_type = Ifc2x3::Type::FromString(TokenFunc::asString(datatype));
438460
}
@@ -502,7 +524,13 @@ unsigned int Entity::id() { return _id; }
502524
// Gets the unit definitins from the file
503525
//
504526
bool Ifc::Init(const std::string& fn) {
505-
file = new File (fn);
527+
return Ifc::Init(new File(fn));
528+
}
529+
bool Ifc::Init(std::istream& f, int len) {
530+
return Ifc::Init(new File(f,len));
531+
}
532+
bool Ifc::Init(IfcParse::File* f) {
533+
file = f;
506534
if ( ! file->valid ) return false;
507535
tokens = new Tokens (file);
508536
Token token = 0;
@@ -545,9 +573,14 @@ bool Ifc::Init(const std::string& fn) {
545573
}
546574

547575
if ( log1 ) std::cout << "\rDone scanning file " << std::endl;
548-
549-
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *EntitiesByType<Ifc2x3::IfcUnitAssignment>()->begin();
550-
IfcUtil::IfcAbstractSelect::list units = unit_assignment->Units();
576+
577+
Ifc2x3::IfcUnitAssignment::list unit_assignments = EntitiesByType<Ifc2x3::IfcUnitAssignment>();
578+
IfcUtil::IfcAbstractSelect::list units = IfcUtil::IfcAbstractSelect::list();
579+
if ( unit_assignments->Size() ) {
580+
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *unit_assignments->begin();
581+
IfcUtil::IfcAbstractSelect::list units = unit_assignment->Units();
582+
}
583+
if ( units )
551584
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
552585
const IfcUtil::IfcAbstractSelect::ptr base = *it;
553586
Ifc2x3::IfcSIUnit::ptr unit = Ifc2x3::IfcSIUnit::ptr();

src/ifcparse/IfcParse.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ namespace IfcParse {
6161
unsigned int len;
6262
unsigned int offset;
6363
void ReadBuffer(bool inc=true);
64+
bool paging;
6465
public:
6566
bool valid;
6667
bool eof;
6768
unsigned int size;
6869
File(const std::string& fn);
70+
File(std::istream& f, int len);
6971
char Peek();
7072
char Read(unsigned int offset);
7173
void Inc();
@@ -258,16 +260,19 @@ class Ifc {
258260
template <class T>
259261
static typename T::list EntitiesByType() {
260262
IfcEntities e = EntitiesByType(T::Class());
261-
typename T::list l ( new IfcTemplatedEntityList<T>() ); \
262-
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \
263-
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));\
263+
typename T::list l ( new IfcTemplatedEntityList<T>() );
264+
if ( e && e->Size() )
265+
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
266+
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));
264267
}
265268
return l;
266269
}
267270
static IfcEntities EntitiesByType(Ifc2x3::Type::Enum t);
268271
static IfcEntities EntitiesByReference(int id);
269272
static IfcEntity EntityById(int id);
270273
static bool Init(const std::string& fn);
274+
static bool Init(std::istream& fn, int len);
275+
static bool Init(IfcParse::File* f);
271276
static void Dispose();
272277
static float LengthUnit;
273278
static float PlaneAngleUnit;

src/ifcserver/IfcServer.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/********************************************************************************
2+
* *
3+
* This file is part of IfcOpenShell. *
4+
* *
5+
* IfcOpenShell is free software: you can redistribute it and/or modify *
6+
* it under the terms of the Lesser GNU General Public License as published by *
7+
* the Free Software Foundation, either version 3.0 of the License, or *
8+
* (at your option) any later version. *
9+
* *
10+
* IfcOpenShell is distributed in the hope that it will be useful, *
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13+
* Lesser GNU General Public License for more details. *
14+
* *
15+
* You should have received a copy of the Lesser GNU General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
* *
18+
********************************************************************************/
19+
20+
/********************************************************************************
21+
* *
22+
* This examples exposes the IfcOpenShell API through a command-based stdin *
23+
* interface *
24+
* *
25+
********************************************************************************/
26+
27+
#include <iostream>
28+
29+
#include "../ifcparse/IfcGeomObjects.h"
30+
31+
#if defined(WIN32) && !defined(__CYGWIN__)
32+
#include <io.h>
33+
#include <fcntl.h>
34+
#endif
35+
36+
int main ( int argc, char** argv ) {
37+
#if defined(WIN32) && !defined(__CYGWIN__)
38+
_setmode(_fileno(stdout), _O_BINARY);
39+
std::cout.setf(std::ios_base::binary);
40+
#endif
41+
bool has_more = false;
42+
std::cout.write("IfcOpenShell-0.2.0",18);
43+
std::cout.flush();
44+
const IfcGeomObjects::IfcGeomObject* ifc_geom = 0;
45+
while (1) {
46+
std::string command;
47+
std::cin >> command;
48+
if ( command == "load" ) {
49+
std::string fn;
50+
std::getline(std::cin,fn);
51+
fn = fn.erase(0,fn.find_first_not_of(" "));
52+
has_more = IfcGeomObjects::Init(fn.c_str(),true,0,&std::cerr);
53+
std::cout.write(has_more ? "y" : "n",1);
54+
std::cout.flush();
55+
} else if ( command == "loadstdin" ) {
56+
std::cout << "ok" << std::flush;
57+
int len;
58+
std::cin >> len;
59+
std::cout << "ok" << std::flush;
60+
has_more = IfcGeomObjects::Init(std::cin,len,true,0,&std::cerr);
61+
std::cout.write(has_more ? "y" : "n",1);
62+
std::cout.flush();
63+
} else if ( command == "get" ) {
64+
if ( !has_more ) {
65+
std::cout << "Not loaded" << std::flush;
66+
} else {
67+
ifc_geom = IfcGeomObjects::Get();
68+
const int vcount = ifc_geom->mesh->verts.size() / 3;
69+
std::cout.write((char*)&vcount,sizeof(int));
70+
std::cout.write((char*)&ifc_geom->mesh->verts[0],sizeof(float)*vcount*3);
71+
const int fcount = ifc_geom->mesh->faces.size() / 3;
72+
std::cout.write((char*)&fcount,sizeof(int));
73+
std::cout.write((char*)&ifc_geom->mesh->faces[0],sizeof(int)*fcount*3);
74+
std::cout.flush();
75+
}
76+
} else if ( command == "type" ) {
77+
if ( ! ifc_geom ) {
78+
std::cout << "Not loaded" << std::flush;
79+
} else {
80+
std::cout << ifc_geom->type << std::flush;
81+
}
82+
} else if ( command == "guid" ) {
83+
if ( ! ifc_geom ) {
84+
std::cout << "Not loaded" << std::flush;
85+
} else {
86+
std::cout << ifc_geom->name << std::flush;
87+
}
88+
} else if ( command == "next" ) {
89+
if ( !has_more ) {
90+
std::cout << "Not loaded" << std::flush;
91+
} else {
92+
has_more = IfcGeomObjects::Next();
93+
std::cout.write(has_more ? "y" : "n",1);
94+
std::cout.flush();
95+
}
96+
} else if ( command == "quit" || command == "exit" ) {
97+
std::cout << "Bye" << std::flush;
98+
break;
99+
} else {
100+
std::cout << "Unknown command " << command << std::flush;
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)