Hi @ferdinand
You've understood everything perfectly correct.
Yes, I want to add a lot of objects in the scene,
Yes, when its number is 250, it is not the problem at all. The talking about case when the number is 3000.
// The function is called from the ObjectDataPlugin Messages.
doc->StartUndo();
// Alloc() all
// MainThread
maxon::TimeValue timer = maxon::TimeValue::GetTime();
ApplicationOutput("Starting Alloc()...@", timer.GetSeconds());
for (Int32 i = 0; i <= amount; ++i) // 3000
{
BaseObject* const joint = BaseObject::Alloc(Osphere);
BaseObject* const cyl = BaseObject::Alloc(Ocylinder);
BaseObject* const connector = BaseObject::Alloc(180000011);
BaseObject* const upV = BaseObject::Alloc(Onull);
BaseTag* const DBtag = BaseTag::Alloc(180000102);
BaseTag* const Constraint1 = BaseTag::Alloc(1019364);
BaseTag* const Constraint2 = BaseTag::Alloc(1019364);
joints.push_back(joint); cylinders.push_back(cyl); connectors.push_back(connector); UpVs.push_back(upV);
DBtags.push_back(DBtag); constTags1.push_back(Constraint1); constTags2.push_back(Constraint2);
}
// ParallelFor. Sort, set params
timer = maxon::TimeValue::GetTime();
ApplicationOutput("Starting ParallelFor...@", timer.GetSeconds());
// Worker lambda
auto worker = [amount, modifyOnly, &controller1, &controller2, ...etc ](maxon::Int32 i)
{
{
joints.at(i)->SetParameter(ID_BASELIST_NAME, spline->GetName() + String::IntToString(i), DESCFLAGS_SET::NONE);
joints.at(i)->SetParameter(...etc
Vector firstpos = ... // calculate some points
cylinders.at(i)->SetParameter(ID_BASELIST_NAME, spline->GetName() + String::IntToString(i), DESCFLAGS_SET::NONE);
cylinders.at(i)->SetParameter(...
if (.... some calculation)
{
joints.at(i)->SetMg(BuildLookAt(~controller1->GetMg() * firstpos, ~controller1->GetMg() * secondpos, joints.at(i)->GetMg().sqmat.v3));
}
cylinders.at(i)->SetRelPos(Vector(0, GetDistance(firstpos, secondpos) / 2, 0));
....etc.... // a lot of calculations and setParams, setpos, setMg. No insertion in the scene here.
};
// Assync
maxon::ParallelFor::Dynamic(0, amount+1, worker ); // works nice and fast
// Now an easy but most slow part: objs insertion into the scene
// Main thread.
timer = maxon::TimeValue::GetTime();
ApplicationOutput("Starting Insert()...@", timer.GetSeconds());
for (int j = 0; j < joints.size(); j++)
{
// DB-class
joints.at(j)->InsertTag(DBtags.at(j));
CreatedObjsList->InsertObject(DBtags.at(j), 0);
AdditionalCreatdObjsList->InsertObject(DBtags.at(j), 0);
// joints
joints.at(j)->InsertUnder(controller2);
SpecBonesField->InsertObject(joints.at(j), 0);
/*doc->AddUndo(UNDOTYPE::NEWOBJ, joints.at(j));*/
// Cylinder
cylinders.at(j)->InsertUnder(joints.at(j));
CreatedObjsList->InsertObject(joints.at(j), 0);
CreatedObjsList->InsertObject(cylinders.at(j), 0);
AdditionalCreatdObjsList->InsertObject(joints.at(j), 0);
AdditionalCreatdObjsList->InsertObject(cylinders.at(j), 0);
/*doc->AddUndo(UNDOTYPE::NEWOBJ, cylinders.at(j));*/
// Connector-class
if (simple bool)
{
UpVs.at(j)->InsertUnderLast(parentNull);
CreatedObjsList->InsertObject(UpVs.at(j), 0);
AdditionalCreatdObjsList->InsertObject(UpVs.at(j), 0);
/*doc->AddUndo(UNDOTYPE::NEWOBJ, UpVs.at(j));*/
connectors.at(j)->InsertTag(constTags1.at(j));
connectors.at(j)->InsertTag(constTags2.at(j));
connectors.at(j)->InsertUnderLast(parentNull);
CreatedObjsList->InsertObject(connectors.at(j), 0);
AdditionalCreatdObjsList->InsertObject(connectors.at(j), 0);
/*doc->AddUndo(UNDOTYPE::NEWOBJ, connectors.at(j)); */
// tracer in-Ex
tracerInEx->InsertObject(connectors.at(j), 0);
}
//doc->AddUndo(UNDOTYPE::NEWOBJ, DBtags.at(j));
}
timer = maxon::TimeValue::GetTime();
ApplicationOutput("Ending Insert()...@", timer.GetSeconds());
doc->EndUndo();
If I exclude from the "slow part" everything about InExData, it works much faster. Even when the number of objects is really big (3000). I was thinking about the AddUndo(), that it causes the problem, but - no. When I exclude it too, it does not affect the speed of the "slow" step at all.
So my thoughts was exactly about the InExData causes the slowing down.