diff --git a/src/ifcgeom/IfcGeomObjects.cpp b/src/ifcgeom/IfcGeomObjects.cpp index f2ac3029af..993ac82a62 100644 --- a/src/ifcgeom/IfcGeomObjects.cpp +++ b/src/ifcgeom/IfcGeomObjects.cpp @@ -43,16 +43,20 @@ #include "../ifcgeom/IfcGeom.h" // Welds vertices that belong to different faces +bool weld_vertices = true; int IfcGeomObjects::IfcMesh::addvert(const gp_XYZ& p) { const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z(); - const VertKey key = VertKey(X,std::pair(Y,Z)); - VertKeyMap::const_iterator it = welds.find(key); - if ( it != welds.end() ) return it->second; + int i = verts.size() / 3; + if ( weld_vertices ) { + const VertKey key = VertKey(X,std::pair(Y,Z)); + VertKeyMap::const_iterator it = welds.find(key); + if ( it != welds.end() ) return it->second; + i = (int) welds.size(); + welds[key] = i; + } verts.push_back(X); verts.push_back(Y); verts.push_back(Z); - int i = (int) welds.size(); - welds[key] = i; return i; } @@ -239,8 +243,9 @@ IfcGeomObjects::IfcGeomObject* _get() { } catch (...) {} // Does the IfcElement have any IfcOpenings? + // Note that openings for IfcOpeningElements are not processed Ifc2x3::IfcRelVoidsElement::list openings = Ifc2x3::IfcRelVoidsElement::list(); - if ( ifc_product->is(Ifc2x3::Type::IfcElement) ) { + if ( ifc_product->is(Ifc2x3::Type::IfcElement) && !ifc_product->is(Ifc2x3::Type::IfcOpeningElement) ) { Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast(ifc_product); openings = element->HasOpenings(); } @@ -422,6 +427,25 @@ bool IfcGeomObjects::Init(std::istream& f, int len, bool world_coords, std::ostr total = shapereps->Size(); return true; } +bool IfcGeomObjects::Init(void* data, int len) { + Ifc::SetOutput(0,0); + use_world_coords = true; + weld_vertices = false; + if ( !Ifc::Init(data, len) ) return false; + + shapereps = Ifc::EntitiesByType(); + if ( ! shapereps ) return false; + + outer = shapereps->begin(); + entities.reset(); + current_geom_obj = _get(); + + if ( ! current_geom_obj ) return false; + + done = 0; + total = shapereps->Size(); + return true; +} int IfcGeomObjects::Progress() { return 100 * done / total; } diff --git a/src/ifcgeom/IfcGeomObjects.h b/src/ifcgeom/IfcGeomObjects.h index e327c9d244..c85a16baf7 100644 --- a/src/ifcgeom/IfcGeomObjects.h +++ b/src/ifcgeom/IfcGeomObjects.h @@ -113,6 +113,7 @@ namespace IfcGeomObjects { bool Init(const char* fn, bool world_coords = false); bool Init(const char* fn, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0); bool Init(std::istream& f, int len, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0); + bool Init(void* data, int len); bool CleanUp(); const IfcGeomObject* Get(); bool Next(); diff --git a/src/ifcjni/IfcJni.cpp b/src/ifcjni/IfcJni.cpp new file mode 100644 index 0000000000..ced1bf24fb --- /dev/null +++ b/src/ifcjni/IfcJni.cpp @@ -0,0 +1,72 @@ +/******************************************************************************** + * * + * 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 . * + * * + ********************************************************************************/ + +/******************************************************************************** + * * + * This is a JNI interface to IfcOpenShell for use with the open source * + * http://BIMserver.org * + * * + ********************************************************************************/ + +#include "org_ifcopenshell_IfcOpenShellModel.h" +#include "../ifcgeom/IfcGeomObjects.h" + +bool has_more = false; + +JNIEXPORT jobject JNICALL Java_org_ifcopenshell_IfcOpenShellModel_getGeometry (JNIEnv * env, jobject) { + if ( ! has_more ) return 0; + jclass class_def = env->FindClass ("org/ifcopenshell/IfcGeomObject"); + if ( ! class_def ) return 0; + jmethodID jconstructor = env->GetMethodID(class_def, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[F[F)V"); + if ( ! jconstructor ) return 0; + const IfcGeomObjects::IfcGeomObject* o = IfcGeomObjects::Get(); + + jstring name = env->NewStringUTF(o->name.c_str()); + jstring type = env->NewStringUTF(o->type.c_str()); + jstring guid = env->NewStringUTF(o->guid.c_str()); + + jintArray indices = env->NewIntArray(o->mesh->faces.size()); + jfloatArray positions = env->NewFloatArray(o->mesh->verts.size()); + jfloatArray normals = env->NewFloatArray(o->mesh->verts.size()); + + env->SetIntArrayRegion(indices,0,o->mesh->faces.size(),(jint*) &o->mesh->faces[0]); + env->SetFloatArrayRegion(positions,0,o->mesh->verts.size(),(jfloat*) &o->mesh->verts[0]); + + jobject return_obj = env->NewObject(class_def, jconstructor, name, type, guid, indices, positions, normals); + + env->DeleteLocalRef(name); + env->DeleteLocalRef(type); + env->DeleteLocalRef(guid); + env->DeleteLocalRef(indices); + env->DeleteLocalRef(positions); + env->DeleteLocalRef(normals); + env->DeleteLocalRef(class_def); + + has_more = IfcGeomObjects::Next(); + if ( ! has_more ) IfcGeomObjects::CleanUp(); + + return return_obj; +} + +JNIEXPORT bool JNICALL Java_org_ifcopenshell_IfcOpenShellModel_setIfcData (JNIEnv * env, jobject, jbyteArray jdata) { + void* data = env->GetByteArrayElements(jdata, NULL); + const int length = env->GetArrayLength(jdata); + if ( ! data || ! length ) return false; + return has_more = IfcGeomObjects::Init(data,length); +} \ No newline at end of file diff --git a/src/ifcjni/org_ifcopenshell_IfcOpenShellModel.h b/src/ifcjni/org_ifcopenshell_IfcOpenShellModel.h new file mode 100644 index 0000000000..f4ec8fe6f5 --- /dev/null +++ b/src/ifcjni/org_ifcopenshell_IfcOpenShellModel.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_ifcopenshell_IfcOpenShellModel */ + +#ifndef _Included_org_ifcopenshell_IfcOpenShellModel +#define _Included_org_ifcopenshell_IfcOpenShellModel +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_ifcopenshell_IfcOpenShellModel + * Method: getGeometry + * Signature: ()Lorg/bimserver/plugins/ifcengine/IfcEngineGeometry; + */ +JNIEXPORT jobject JNICALL Java_org_ifcopenshell_IfcOpenShellModel_getGeometry + (JNIEnv *, jobject); + +/* + * Class: org_ifcopenshell_IfcOpenShellModel + * Method: setIfcData + * Signature: ([B)V + */ +JNIEXPORT bool JNICALL Java_org_ifcopenshell_IfcOpenShellModel_setIfcData + (JNIEnv *, jobject, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/ifcparse/IfcFile.h b/src/ifcparse/IfcFile.h index 02d48dedfb..52f5381111 100644 --- a/src/ifcparse/IfcFile.h +++ b/src/ifcparse/IfcFile.h @@ -49,6 +49,7 @@ namespace IfcParse { unsigned int size; File(const std::string& fn); File(std::istream& f, int len); + File(void* data, int len); char Peek(); char Read(unsigned int offset); void Inc(); diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index aa2c986d52..ee22066d64 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -62,6 +62,17 @@ File::File(std::istream& f, int l) { offset = 0; } +File::File(void* data, int l) { + eof = false; + size = l; + paging = false; + buffer = (char*) data; + valid = true; + ptr = 0; + len = l; + offset = 0; +} + void File::Close() { stream.close(); delete[] buffer; @@ -553,6 +564,9 @@ bool Ifc::Init(const std::string& fn) { bool Ifc::Init(std::istream& f, int len) { return Ifc::Init(new File(f,len)); } +bool Ifc::Init(void* data, int len) { + return Ifc::Init(new File(data,len)); +} bool Ifc::Init(IfcParse::File* f) { Ifc2x3::InitStringMap(); file = f; diff --git a/src/ifcparse/IfcParse.h b/src/ifcparse/IfcParse.h index effeae5bb6..8370a976ae 100644 --- a/src/ifcparse/IfcParse.h +++ b/src/ifcparse/IfcParse.h @@ -243,6 +243,7 @@ public: static IfcEntity EntityById(int id); static bool Init(const std::string& fn); static bool Init(std::istream& fn, int len); + static bool Init(void* data, int len); static bool Init(IfcParse::File* f); static std::string GetLog(); static void Dispose(); diff --git a/src/ifcserver/IfcServer.cpp b/src/ifcserver/IfcServer.cpp index 7151f05933..35f98bac4d 100644 --- a/src/ifcserver/IfcServer.cpp +++ b/src/ifcserver/IfcServer.cpp @@ -26,21 +26,37 @@ #include -#include "../ifcparse/IfcGeomObjects.h" +#include "../ifcgeom/IfcGeomObjects.h" #if defined(WIN32) && !defined(__CYGWIN__) #include #include #endif +#define PRODUCT ("IfcOpenShell-0.2.3") +#define ACK ("y") +#define NEG ("n") +#define CONFIRM ("ok") +#define CLOSED ("No opened file") +#define QUIT ("Bye :)") +#define UNKNOWN ("Unknown command") + +void send_msg(const char* c) { + std::cout.write(c,strlen(c)); + std::cout.flush(); +} + +void send_msg(const std::string& s) { + std::cout << s << std::flush; +} + 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(); + send_msg(PRODUCT); const IfcGeomObjects::IfcGeomObject* ifc_geom = 0; while (1) { std::string command; @@ -50,20 +66,17 @@ int main ( int argc, char** argv ) { 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(); + send_msg(has_more ? ACK : NEG); } else if ( command == "loadstdin" ) { - std::cout << "ok" << std::flush; + send_msg(CONFIRM); int len; std::cin >> len; - std::cout << "ok" << std::flush; + send_msg(CONFIRM); has_more = IfcGeomObjects::Init(std::cin,len,true,0,&std::cerr); - std::cout.write(has_more ? "y" : "n",1); - std::cout.flush(); + send_msg(has_more ? ACK : NEG); } else if ( command == "get" ) { - if ( !has_more ) { - std::cout << "Not loaded" << std::flush; - } else { + if ( ! has_more ) send_msg(CLOSED); + else { ifc_geom = IfcGeomObjects::Get(); const int vcount = ifc_geom->mesh->verts.size() / 3; std::cout.write((char*)&vcount,sizeof(int)); @@ -74,30 +87,25 @@ int main ( int argc, char** argv ) { std::cout.flush(); } } else if ( command == "type" ) { - if ( ! ifc_geom ) { - std::cout << "Not loaded" << std::flush; - } else { - std::cout << ifc_geom->type << std::flush; - } + if ( ifc_geom ) send_msg(ifc_geom->type); + else send_msg(CLOSED); } else if ( command == "guid" ) { - if ( ! ifc_geom ) { - std::cout << "Not loaded" << std::flush; - } else { - std::cout << ifc_geom->name << std::flush; - } + if ( ifc_geom ) send_msg(ifc_geom->guid); + else send_msg(CLOSED); } else if ( command == "next" ) { - if ( !has_more ) { - std::cout << "Not loaded" << std::flush; - } else { + if ( !has_more ) send_msg(CLOSED); + else { has_more = IfcGeomObjects::Next(); - std::cout.write(has_more ? "y" : "n",1); - std::cout.flush(); + if ( ! has_more ) + IfcGeomObjects::CleanUp(); + send_msg(has_more ? ACK : NEG); } } else if ( command == "quit" || command == "exit" ) { - std::cout << "Bye" << std::flush; + send_msg(QUIT); break; } else { - std::cout << "Unknown command " << command << std::flush; + send_msg(UNKNOWN); } } + return 0; }