int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL suppressPrompts) { IfcGeom::IteratorSettings settings; settings.use_world_coords() = false; settings.weld_vertices() = true; settings.sew_shells() = true; #ifdef _UNICODE int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0); char* fn_mb = new char[fn_buffer_size]; WideCharToMultiByte(CP_UTF8, 0, name, -1, fn_mb, fn_buffer_size, 0, 0); #else const char* fn_mb = name; #endif IfcGeom::Iterator<float> iterator(settings, fn_mb); if (!iterator.initialize()) return false; itfc->ProgressStart(_T("Importing file..."), TRUE, fn, NULL); MtlBaseLib* mats = itfc->GetSceneMtls(); int slot = mats->Count(); std::map<std::vector<std::string>, Mtl*> material_cache; do{ const IfcGeom::TriangulationElement<float>* o = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator.get()); TSTR o_type = S(o->type()); TSTR o_guid = S(o->guid()); Mtl *m = ComposeMultiMaterial(material_cache, mats, itfc, slot, o->geometry().materials(), o->type(), o->geometry().material_ids()); TriObject* tri = CreateNewTriObject(); const int numVerts = o->geometry().verts().size()/3; tri->mesh.setNumVerts(numVerts); for( int i = 0; i < numVerts; i ++ ) { tri->mesh.setVert(i,o->geometry().verts()[3*i+0],o->geometry().verts()[3*i+1],o->geometry().verts()[3*i+2]); } const int numFaces = o->geometry().faces().size()/3; tri->mesh.setNumFaces(numFaces); bool needs_default = std::find(o->geometry().material_ids().begin(), o->geometry().material_ids().end(), -1) != o->geometry().material_ids().end(); typedef std::pair<int, int> edge_t; std::set<edge_t> face_boundaries; for(std::vector<int>::const_iterator it = o->geometry().edges().begin(); it != o->geometry().edges().end();) { const int v1 = *it++; const int v2 = *it++; const edge_t e((std::min)(v1, v2), (std::max)(v1, v2)); face_boundaries.insert(e); } for( int i = 0; i < numFaces; i ++ ) { const int v1 = o->geometry().faces()[3*i+0]; const int v2 = o->geometry().faces()[3*i+1]; const int v3 = o->geometry().faces()[3*i+2]; const edge_t e1((std::min)(v1, v2), (std::max)(v1, v2)); const edge_t e2((std::min)(v2, v3), (std::max)(v2, v3)); const edge_t e3((std::min)(v3, v1), (std::max)(v3, v1)); const bool b1 = face_boundaries.find(e1) != face_boundaries.end(); const bool b2 = face_boundaries.find(e2) != face_boundaries.end(); const bool b3 = face_boundaries.find(e3) != face_boundaries.end(); tri->mesh.faces[i].setVerts(v1, v2, v3); tri->mesh.faces[i].setEdgeVisFlags(b1, b2, b3); MtlID mtlid = o->geometry().material_ids()[i]; if (needs_default) { mtlid ++; } tri->mesh.faces[i].setMatID(mtlid); } tri->mesh.buildNormals(); // Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have // properly oriented normals. Using only the line below will result in a consistent // orientation of normals accross shells, but not always oriented towards the // outside. // tri->mesh.UnifyNormals(false); tri->mesh.BuildStripsAndEdges(); tri->mesh.InvalidateTopologyCache(); tri->mesh.InvalidateGeomCache(); ImpNode* node = impitfc->CreateNode(); node->Reference(tri); node->SetName(o_guid); node->GetINode()->Hide(o->type() == "IfcOpeningElement" || o->type() == "IfcSpace"); if (m) { node->GetINode()->SetMtl(m); } const std::vector<float>& matrix_data = o->transformation().matrix().data(); node->SetTransform(0,Matrix3 ( Point3(matrix_data[0],matrix_data[1],matrix_data[2]),Point3(matrix_data[3],matrix_data[4],matrix_data[5]), Point3(matrix_data[6],matrix_data[7],matrix_data[8]),Point3(matrix_data[9],matrix_data[10],matrix_data[11]) )); impitfc->AddNodeToScene(node); itfc->ProgressUpdate(iterator.progress(), true, _T("")); } while (iterator.next()); itfc->ProgressEnd(); return true; }
int main () { // 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; IfcGeom::Iterator<float>* iterator = 0; Hello().write(std::cout); int exit_code = 0; for (;;) { const int32_t msg_type = sread<int32_t>(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); IfcGeom::IteratorSettings settings; settings.use_world_coords() = false; settings.weld_vertices() = false; settings.convert_back_units() = true; settings.include_curves() = true; iterator = new IfcGeom::Iterator<float>(settings, data, (int)len); has_more = iterator->initialize(); More(has_more).write(std::cout); continue; } case GET: { Get g; g.read(std::cin); if (!has_more) { exit_code = 1; break; } const IfcGeom::TriangulationElement<float>* geom = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator->get()); Entity(geom).write(std::cout); continue; } case NEXT: { Next n; n.read(std::cin); has_more = iterator->next(); if (!has_more) { delete iterator; iterator = 0; } More(has_more).write(std::cout); continue; } case GET_LOG: { GetLog gl; gl.read(std::cin); WriteLog(iterator->getLog()).write(std::cout); continue; } case BYE: { Bye().write(std::cout); exit_code = 0; break; } default: exit_code = 1; break; } break; } std::cout.rdbuf(stdout_orig); return exit_code; }