diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 07a9ee6161..5fe6e41e22 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -165,6 +165,12 @@ ADD_EXECUTABLE(IfcConvert TARGET_LINK_LIBRARIES (IfcConvert IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES TKOffset ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES}) +ADD_EXECUTABLE(IfcGeomServer + ../src/ifcgeomserver/IfcGeomServer.cpp +) + +TARGET_LINK_LIBRARIES (IfcGeomServer IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES TKOffset) + # Build python wrapper using separate CMakeLists.txt ADD_SUBDIRECTORY(../src/ifcwrap ifcwrap) diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp new file mode 100644 index 0000000000..0b33299346 --- /dev/null +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -0,0 +1,321 @@ +/******************************************************************************** + * * + * 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 examples exposes the IfcOpenShell API through a command-based stdin * + * interface * + * * + ********************************************************************************/ + +#include +#include + +#if defined(_WIN32) && !defined(__CYGWIN__) +#define SET_BINARY_STREAMS +#endif +#ifdef SET_BINARY_STREAMS +#include +#include +#endif + +#include "../ifcgeom/IfcGeomObjects.h" + +using namespace boost; + +template +T sread(std::istream& s) { + char buf[sizeof(T)]; + s.read(buf, sizeof(T)); + return *((T*)buf); +} + +template <> +std::string sread(std::istream& s) { + int32_t len = sread(s); + char* buf = new char[len + 1]; + s.read(buf, len); + buf[len] = 0; + while (len++ % 4) s.get(); + std::string str(buf); + delete buf; + return str; +} + +static std::streambuf *stdout_orig, *stdout_redir; + +template +void swrite(std::ostream& s, T t) { + char buf[sizeof(T)]; + memcpy(buf, &t, sizeof(T)); + s.write(buf, sizeof(T)); +} + +template <> +void swrite(std::ostream& s, std::string t) { + int32_t len = t.size(); + swrite(s, len); + s.write(t.c_str(), len); + while (len++ % 4) s.put(0); +} + +class Command { +protected: + virtual void read_content(std::istream& s) = 0; + virtual void write_content(std::ostream& s) = 0; + int32_t iden; + int32_t len; +public: + void read(std::istream& s) { + len = sread(s); + read_content(s); + } + + void write(std::ostream& s) { + std::cout.rdbuf(stdout_orig); + swrite(s, iden); + std::ostringstream oss; + write_content(oss); + swrite(s, oss.str()); + s.flush(); + std::cout.rdbuf(stdout_redir); + } + + Command(int32_t iden) : iden(iden) {} +}; + +const int32_t HELLO = 0xff00; +const int32_t IFC_MODEL = HELLO + 1; +const int32_t GET = IFC_MODEL + 1; +const int32_t ENTITY = GET + 1; +const int32_t MORE = ENTITY + 1; +const int32_t NEXT = MORE + 1; +const int32_t BYE = NEXT + 1; +const int32_t GET_LOG = BYE + 1; +const int32_t LOG = GET_LOG + 1; + +class Hello : public Command { +private: + std::string str; +protected: + void read_content(std::istream& s) { + str = sread(s); + } + void write_content(std::ostream& s) { + swrite(s, str); + } +public: + const std::string& string() { return str; } + Hello() : Command(HELLO), str("IfcOpenShell-" IFCOPENSHELL_VERSION) {} +}; + +class More : public Command { +private: + bool more; +protected: + void read_content(std::istream& s) { + more = sread(s) == 1; + } + void write_content(std::ostream& s) { + swrite(s, more ? 1 : 0); + } +public: + More(bool more) : Command(MORE), more(more) {} +}; + +class IfcModel : public Command { +private: + std::string str; +protected: + void read_content(std::istream& s) { + str = sread(s); + } + void write_content(std::ostream& s) { + swrite(s, str); + } +public: + const std::string& string() { return str; } + IfcModel() : Command(IFC_MODEL) {}; +}; + +class Get : public Command { +protected: + void read_content(std::istream& s) {} + void write_content(std::ostream& s) {} +public: + Get() : Command(GET) {}; +}; + +class GetLog : public Command { +protected: + void read_content(std::istream& s) {} + void write_content(std::ostream& s) {} +public: + GetLog() : Command(GET_LOG) {}; +}; + +class WriteLog : public Command { +private: + std::string str; +protected: + void read_content(std::istream& s) { + str = sread(s); + } + void write_content(std::ostream& s) { + swrite(s, str); + } +public: + WriteLog(const std::string& str) : Command(LOG), str(str) {}; +}; + +class Entity : public Command { +private: + const IfcGeomObjects::IfcGeomObject* geom; +protected: + void read_content(std::istream& s) {} + void write_content(std::ostream& s) { + swrite(s, geom->id()); + swrite(s, geom->guid()); + swrite(s, geom->name()); + swrite(s, geom->type()); + swrite(s, geom->parent_id()); + swrite(s, std::string((char*)geom->matrix().data(), 16 * sizeof(float))); + swrite(s, geom->mesh().id()); + swrite(s, std::string((char*)geom->mesh().verts().data(), geom->mesh().verts().size() * sizeof(float))); + swrite(s, std::string((char*)geom->mesh().normals().data(), geom->mesh().normals().size() * sizeof(float))); + { std::vector indices; + for (std::vector::const_iterator it = geom->mesh().faces().begin(); it != geom->mesh().faces().end(); ++it) { + indices.push_back(*it); + } + swrite(s, std::string((char*) indices.data(), indices.size() * sizeof(int32_t))); } + { std::vector diffuse_color_array; + for (std::vector::const_iterator it = geom->mesh().materials().begin(); it != geom->mesh().materials().end(); ++it) { + const auto& m = *it; + if (m.hasDiffuse()) { + const double* color = m.diffuse(); + diffuse_color_array.push_back(static_cast(color[0])); + diffuse_color_array.push_back(static_cast(color[1])); + diffuse_color_array.push_back(static_cast(color[2])); + } else { + diffuse_color_array.push_back(0.f); + diffuse_color_array.push_back(0.f); + diffuse_color_array.push_back(0.f); + } + if (m.hasTransparency()) { + diffuse_color_array.push_back(static_cast(1. - m.transparency())); + } else { + diffuse_color_array.push_back(1.f); + } + } + swrite(s, std::string((char*) diffuse_color_array.data(), diffuse_color_array.size() * sizeof(float))); } + { std::vector material_indices; + for (std::vector::const_iterator it = geom->mesh().material_ids().begin(); it != geom->mesh().material_ids().end(); ++it) { + material_indices.push_back(*it); + } + swrite(s, std::string((char*) material_indices.data(), material_indices.size() * sizeof(int32_t))); } + } +public: + Entity(const IfcGeomObjects::IfcGeomObject* geom) : Command(ENTITY), geom(geom) {}; +}; + +class Next : public Command { +protected: + void read_content(std::istream& s) {} + void write_content(std::ostream& s) {} +public: + Next() : Command(NEXT) {}; +}; + +class Bye : public Command { +protected: + void read_content(std::istream& s) {} + void write_content(std::ostream& s) {} +public: + Bye() : Command(BYE) {}; +}; + +int main (int argc, char** argv) { + if (sizeof(float) != 4 || sizeof(int32_t) != 4) { + return 1; + } + + // Redirect stdout to this stream, so that involuntary + // writes to stdout do not interfere with our protocol. + std::ostringstream oss; + stdout_redir = oss.rdbuf(); + stdout_orig = std::cout.rdbuf(); + std::cout.rdbuf(stdout_redir); + +#ifdef SET_BINARY_STREAMS + _setmode(_fileno(stdout), _O_BINARY); + std::cout.setf(std::ios_base::binary); + _setmode(_fileno(stdin), _O_BINARY); + std::cin.setf(std::ios_base::binary); +#endif + + bool has_more = false; + + Hello().write(std::cout); + while (1) { + const int32_t msg_type = sread(std::cin); + switch (msg_type) { + case IFC_MODEL: { + IfcModel m; m.read(std::cin); + std::string::size_type len = m.string().size(); + char* data = new char[len]; + memcpy(data, m.string().c_str(), len); + + IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, false); + IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES, false); + IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS, true); + IfcGeomObjects::Settings(IfcGeomObjects::FORCE_CCW_FACE_ORIENTATION, true); + + has_more = IfcGeomObjects::Init(data, len); + More(has_more).write(std::cout); + break; + } + case GET: { + Get g; g.read(std::cin); + if (!has_more) return 1; + const IfcGeomObjects::IfcGeomObject* geom = IfcGeomObjects::Get(); + Entity(geom).write(std::cout); + break; + } + case NEXT: { + Next n; n.read(std::cin); + has_more = IfcGeomObjects::Next(); + if (!has_more) { + IfcGeomObjects::CleanUp(); + } + More(has_more).write(std::cout); + break; + } + case GET_LOG: { + GetLog gl; gl.read(std::cin); + WriteLog(IfcGeomObjects::GetLog()).write(std::cout); + break; + } + case BYE: { + Bye().write(std::cout); + return 0; + } + default: return 1; + } + } +} diff --git a/src/ifcserver/IfcServer.cpp b/src/ifcserver/IfcServer.cpp deleted file mode 100644 index c0563dcb5a..0000000000 --- a/src/ifcserver/IfcServer.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************** - * * - * 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 examples exposes the IfcOpenShell API through a command-based stdin * - * interface * - * * - ********************************************************************************/ - -#include - -#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; - send_msg(PRODUCT); - 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); - send_msg(has_more ? ACK : NEG); - } else if ( command == "loadstdin" ) { - send_msg(CONFIRM); - int len; - std::cin >> len; - send_msg(CONFIRM); - has_more = IfcGeomObjects::Init(std::cin,len,true,0,&std::cerr); - send_msg(has_more ? ACK : NEG); - } else if ( command == "get" ) { - 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)); - 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 ) send_msg(ifc_geom->type); - else send_msg(CLOSED); - } else if ( command == "guid" ) { - if ( ifc_geom ) send_msg(ifc_geom->guid); - else send_msg(CLOSED); - } else if ( command == "next" ) { - if ( !has_more ) send_msg(CLOSED); - else { - has_more = IfcGeomObjects::Next(); - if ( ! has_more ) - IfcGeomObjects::CleanUp(); - send_msg(has_more ? ACK : NEG); - } - } else if ( command == "quit" || command == "exit" ) { - send_msg(QUIT); - break; - } else { - send_msg(UNKNOWN); - } - } - return 0; -}