mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
Sander boer's change for multithreading
1. Added multithread for create element 2. Added support function in IfcConvert.cpp for multithreading at bottom
This commit is contained in:
+136
-48
@@ -787,61 +787,61 @@ int main(int argc, char** argv) {
|
|||||||
Logger::Status("Creating geometry...");
|
Logger::Status("Creating geometry...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
|
/// =============== Sanders approach for multiple threading ============================
|
||||||
// wrap an iterator of all geometrical products in the Ifc file.
|
for (int j = 0; j < (int)IfcproductRepresentations.size(); j++)
|
||||||
// IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or
|
{
|
||||||
// -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
|
IfcproductRepresentation &r = IfcproductRepresentations[j];
|
||||||
// for definition) IfcGeom::Iterator::next() is used to poll whether more
|
create_element(settings, r, kernel2x3);
|
||||||
// geometrical entities are available. None of these functions throw
|
|
||||||
// exceptions, neither for parsing errors or geometrical errors. Upon
|
|
||||||
// calling next() the entity to be returned has already been processed, a
|
|
||||||
// non-null return value guarantees that a successfully processed product is
|
|
||||||
// available.
|
|
||||||
size_t num_created = 0;
|
|
||||||
|
|
||||||
do {
|
if (threadpool.size() < concurrency)
|
||||||
IfcGeom::Element<real_t> *geom_object = context_iterator.get();
|
|
||||||
|
|
||||||
if (is_tesselated)
|
|
||||||
{
|
{
|
||||||
serializer->write(static_cast<const IfcGeom::TriangulationElement<real_t>*>(geom_object));
|
std::future<void> fu = std::async(std::launch::async, create_element, std::ref(settings), std::ref(r), std::ref(kernel2x3));
|
||||||
|
threadpool.emplace_back(std::move(fu));
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serializer->write(static_cast<const IfcGeom::BRepElement<real_t>*>(geom_object));
|
bool waiting = true;
|
||||||
}
|
while (waiting)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)threadpool.size(); i++)
|
||||||
|
{
|
||||||
|
cout << "Thread pool size: " << threadpool.size();
|
||||||
|
std::future<void> &fu = threadpool[i];
|
||||||
|
std::future_status status;
|
||||||
|
status = fu.wait_for(std::chrono::seconds(0));
|
||||||
|
if (status == std::future_status::ready)
|
||||||
|
{
|
||||||
|
fu.get();
|
||||||
|
threadpool.erase(threadpool.begin() + i);
|
||||||
|
waiting = false;
|
||||||
|
} // if
|
||||||
|
} // for
|
||||||
|
} // while
|
||||||
|
} //else
|
||||||
|
}
|
||||||
|
|
||||||
if (!no_progress) {
|
// Serializer
|
||||||
if (quiet) {
|
for (int j = 0; j < (int)IfcproductRepresentations.size(); j++)
|
||||||
const int progress = context_iterator.progress();
|
{
|
||||||
for (; old_progress < progress; ++old_progress) {
|
IfcproductRepresentation *rep = &IfcproductRepresentations[j];
|
||||||
std::cout << ".";
|
//write_element(serializer, rep, is_tesselated);
|
||||||
if (stderr_progress)
|
cout_ << "writing to file, element #: " << rep->index << "\n";
|
||||||
std::cerr << ".";
|
IfcGeom::Element<real_t> *geom_object = rep->element;
|
||||||
}
|
if (geom_object == nullptr)
|
||||||
std::cout << std::flush;
|
{
|
||||||
if (stderr_progress)
|
cout_ << "skipped" << std::endl;
|
||||||
std::cerr << std::flush;
|
continue;
|
||||||
} else {
|
|
||||||
const int progress = context_iterator.progress() / 2;
|
|
||||||
if (old_progress != progress) Logger::ProgressBar(progress);
|
|
||||||
old_progress = progress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (++num_created, context_iterator.next());
|
|
||||||
|
|
||||||
if (!no_progress && quiet) {
|
|
||||||
for (; old_progress < 100; ++old_progress) {
|
|
||||||
std::cout << ".";
|
|
||||||
if (stderr_progress)
|
|
||||||
std::cerr << ".";
|
|
||||||
}
|
}
|
||||||
std::cout << std::flush;
|
if (is_tesselated)
|
||||||
if (stderr_progress)
|
{
|
||||||
std::cerr << std::flush;
|
serializer->write(static_cast<const IfcGeom::TriangulationElement<real_t> *>(geom_object));
|
||||||
} else {
|
}
|
||||||
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(num_created) +
|
else
|
||||||
" objects) ");
|
{
|
||||||
|
serializer->write(static_cast<const IfcGeom::BRepElement<real_t> *>(geom_object));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
serializer->finalize();
|
serializer->finalize();
|
||||||
@@ -1348,3 +1348,91 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////// ***** Added for multithreading ****** /////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool reuse_ok_(SerializerSettings settings, const IfcSchema::IfcProduct::list::ptr &products, IfcGeom::Kernel kernel)
|
||||||
|
{
|
||||||
|
IfcGeom::KernelIfc2x3 kernel2x3;
|
||||||
|
|
||||||
|
if(settings.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::set<const IfcSchema::IfcMaterial *> associated_single_materials;
|
||||||
|
|
||||||
|
for(IfcSchema::IfcProduct::list::it it = products->begin(); it != products->end(); ++it)
|
||||||
|
{
|
||||||
|
IfcSchema::IfcProduct *product = *it;
|
||||||
|
|
||||||
|
if(!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) &&
|
||||||
|
kernel2x3.find_openings(product)->size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (settings.get(IfcGeom::IteratorSettings::APPLY_LAYERSETS))
|
||||||
|
{
|
||||||
|
IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations();
|
||||||
|
for (IfcSchema::IfcRelAssociates::list::it jt = associations->begin(); jt != associations->end(); ++jt)
|
||||||
|
{
|
||||||
|
IfcSchema::IfcRelAssociatesMaterial *assoc = (*jt)->as<IfcSchema::IfcRelAssociatesMaterial>();
|
||||||
|
if (assoc)
|
||||||
|
{
|
||||||
|
//if (assoc->RelatingMaterial()->is(IfcSchema::IfcMaterialLayerSetUsage))
|
||||||
|
if (assoc->RelatingMaterial()->declaration().is(IfcSchema::IfcMaterialLayerSetUsage::Class()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
associated_single_materials.insert(kernel2x3.get_single_material_association(product));
|
||||||
|
if (associated_single_materials.size() > 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return associated_single_materials.size() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_element(boost::shared_ptr<GeometrySerializer> serializer, IfcproductRepresentation *rep, bool is_tesselated)
|
||||||
|
{
|
||||||
|
IfcGeom::Element<real_t> *geom_object = rep->element;
|
||||||
|
if (is_tesselated)
|
||||||
|
{
|
||||||
|
serializer->write(static_cast<const IfcGeom::TriangulationElement<real_t> *>(geom_object));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serializer->write(static_cast<const IfcGeom::BRepElement<real_t> *>(geom_object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_element(SerializerSettings &settings, IfcproductRepresentation &rep, IfcGeom::KernelIfc2x3& kernel2x3)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// is kernel thread-safe ?
|
||||||
|
// @tfk: no, it's not, my advise would be to boot one
|
||||||
|
// kernel instance per thread.
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Logger::Status("processing item #: " + std::to_string(rep.index));
|
||||||
|
IfcSchema::IfcRepresentation *representation = rep.representation;
|
||||||
|
IfcSchema::IfcProduct *product = rep.product;
|
||||||
|
// IfcGeom::BRepElement<real_t> *element;
|
||||||
|
//rep.element = kernel2x3.create_brep_for_representation_and_product<real_t, real_t>(settings, representation, product);
|
||||||
|
rep.brep = kernel2x3.create_brep_for_representation_and_product<real_t, real_t>(settings, representation, product);
|
||||||
|
rep.element = rep.brep ? new IfcGeom::TriangulationElement<double>(*rep.brep) : nullptr;
|
||||||
|
// if(geometry_reuse_ok_for_current_representation_)
|
||||||
|
// {
|
||||||
|
// // element =
|
||||||
|
// kernel.create_brep_for_processed_representation(settings,
|
||||||
|
// representation,
|
||||||
|
// // product,
|
||||||
|
// // current_shape_model);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user