Skip to content

Commit eeec89f

Browse files
authored
[src] Clean SOFA graph creation by creating Actor using TWeekObjectPtr and SpawnActorDeferred (#23)
* Add button to load sofa scene, it should not be called during parameter setting * Qdd option to separate SOFA scene loading and mapping into UE5 * replace vector of raw pointer of DAGNode by RAII TWeakObjectPtr from UE5 * try to use SpawnActorDeferred * some cleaning in SOFA DAGNode
1 parent ec2100d commit eeec89f

4 files changed

Lines changed: 66 additions & 74 deletions

File tree

Source/SofaUE5/Private/DAGNode/SofaDAGNode.cpp

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,6 @@ void ASofaDAGNode::BeginPlay()
5555
}
5656

5757

58-
#if WITH_EDITOR
59-
void ASofaDAGNode::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
60-
{
61-
if (PropertyChangedEvent.MemberProperty != nullptr)
62-
{
63-
FString MemberName = PropertyChangedEvent.MemberProperty->GetName();
64-
//UE_LOG(LogTemp, Warning, TEXT("PostEditChangeProperty: %s"), *MemberName);
65-
66-
if (MemberName.Compare(TEXT("ComponentLoaded")) == 0)
67-
{
68-
loadComponents();
69-
}
70-
}
71-
}
72-
#endif
73-
74-
7558
// Called every frame
7659
void ASofaDAGNode::Tick(float DeltaTime)
7760
{
@@ -108,6 +91,7 @@ bool ASofaDAGNode::loadComponents(SofaAdvancePhysicsAPI* _sofaAPI)
10891
return false;
10992
}
11093

94+
FTransform SpawnTransform = FTransform::Identity;
11195
for (int compoId = 0; compoId < nbrCompo; compoId++)
11296
{
11397
std::string compoName = "";
@@ -138,17 +122,28 @@ bool ASofaDAGNode::loadComponents(SofaAdvancePhysicsAPI* _sofaAPI)
138122
ASofaBaseComponent* component = nullptr;
139123
if (baseType.compare("SofaVisualModel") == 0)
140124
{
141-
component = World->SpawnActor<ASofaVisualMesh>(ASofaVisualMesh::StaticClass(), SpawnParams);
125+
component = World->SpawnActorDeferred<ASofaVisualMesh>(
126+
ASofaVisualMesh::StaticClass(),
127+
SpawnTransform,
128+
this,
129+
nullptr,
130+
ESpawnActorCollisionHandlingMethod::AlwaysSpawn
131+
);
142132
//visuMesh->setSofaMesh(mesh);
143133
}
144134
else
145135
{
146-
component = World->SpawnActor<ASofaBaseComponent>(ASofaBaseComponent::StaticClass(), SpawnParams);
136+
component = World->SpawnActorDeferred<ASofaBaseComponent>(
137+
ASofaBaseComponent::StaticClass(),
138+
SpawnTransform,
139+
this,
140+
nullptr,
141+
ESpawnActorCollisionHandlingMethod::AlwaysSpawn
142+
);
147143
}
148144

149145
if (component != nullptr)
150146
{
151-
bool resAttach = component->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
152147
//if (m_log)
153148
UE_LOG(SUnreal_log, Log, TEXT("### ASofaBaseComponent Created: %s | %s | %s"), *fs_compoName, *fs_displayName, *fs_baseType);
154149

@@ -157,38 +152,23 @@ bool ASofaDAGNode::loadComponents(SofaAdvancePhysicsAPI* _sofaAPI)
157152
component->SetActorLabel(fs_displayName);
158153
component->setSofaAPI(_sofaAPI);
159154
component->computeComponent();
155+
156+
UGameplayStatics::FinishSpawningActor(component, SpawnTransform);
157+
bool resAttach = component->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
160158
}
161159
else
162160
{
163161
UE_LOG(SUnreal_log, Error, TEXT("## ASofaContext::loadComponents: component creation is null"));
164162
}
165163

166164
// Sleep for 10 ms (0.01 seconds)
167-
FPlatformProcess::Sleep(0.01f);
165+
//FPlatformProcess::Sleep(0.01f);
168166
}
169167

170168
return true;
171169
}
172170

173171

174-
void ASofaDAGNode::loadComponents()
175-
{
176-
if (m_statusLoaded == true) // only once
177-
return;
178-
179-
UE_LOG(SUnreal_log, Log, TEXT("## ASofaDAGNode::loadComponents: %s | UniqueID: %s"), *this->GetName(), *this->m_uniqueNameID);
180-
181-
std::string nodeUniqID = std::string(TCHAR_TO_UTF8(*m_uniqueNameID));
182-
m_componentsNames = m_sofaAPI->getDAGNodeComponentsNames(nodeUniqID);
183-
//std::string componentList = m_sofaAPI->getDAGNodeComponentsName(nodeUniqID);
184-
185-
//FString fs_componentList(componentList.c_str());
186-
UE_LOG(SUnreal_log, Log, TEXT("## Process Node: %s | m_componentsNames size: %d"), *this->m_uniqueNameID, m_componentsNames.size());
187-
188-
189-
m_statusLoaded = true;
190-
}
191-
192172
void ASofaDAGNode::reconnectComponents(SofaAdvancePhysicsAPI* _sofaAPI)
193173
{
194174
m_sofaAPI = _sofaAPI;

Source/SofaUE5/Private/SofaContext.cpp

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,8 @@ void ASofaContext::loadNodeGraph()
365365
if (m_sofaAPI == nullptr)
366366
return;
367367

368+
clearNodeGraph();
369+
368370
int nbrNode = m_sofaAPI->getNbrDAGNode();
369371
UE_LOG(SUnreal_log, Warning, TEXT("## ASofaContext::loadNodeGraph: Load Node nbr: %d"), nbrNode);
370372

@@ -375,7 +377,8 @@ void ASofaContext::loadNodeGraph()
375377
return;
376378
}
377379

378-
m_dagNodes.clear();
380+
FTransform SpawnTransform = FTransform::Identity;
381+
379382
// First create all Nodes
380383
for (int nodeId = 0; nodeId < nbrNode; nodeId++)
381384
{
@@ -395,15 +398,21 @@ void ASofaContext::loadNodeGraph()
395398
FString fs_nodeDisplayName(nodeDisplayName.c_str());
396399

397400
FActorSpawnParameters SpawnParams;
398-
SpawnParams.Name = MakeUniqueObjectName(World, ASofaDAGNode::StaticClass(), FName(*fs_nodeDisplayName));
401+
//SpawnParams.Name = MakeUniqueObjectName(World, ASofaDAGNode::StaticClass(), FName(*fs_nodeDisplayName));
399402
SpawnParams.Owner = this;
400403

401-
ASofaDAGNode* dagNode = World->SpawnActor<ASofaDAGNode>(ASofaDAGNode::StaticClass(), SpawnParams);
404+
ASofaDAGNode* dagNode = World->SpawnActorDeferred<ASofaDAGNode>(
405+
ASofaDAGNode::StaticClass(),
406+
SpawnTransform,
407+
this,
408+
nullptr,
409+
ESpawnActorCollisionHandlingMethod::AlwaysSpawn
410+
);
402411

403412
if (dagNode != nullptr)
404413
{
405414
//FAttachmentTransformRules att = FAttachmentTransformRules(EAttachmentRule::KeepRelative, true);
406-
dagNode->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
415+
//dagNode->AttachToActor(this, FAttachmentTransformRules::KeepRelativeTransform);
407416

408417
std::string parentNameId = "";
409418
int resParentNameId = m_sofaAPI->getDAGNodeParentAPIName_out(nodeUniqID, parentNameId);
@@ -418,7 +427,8 @@ void ASofaContext::loadNodeGraph()
418427
if (m_log)
419428
UE_LOG(SUnreal_log, Log, TEXT("### ASofaDAGNode Created: %s | parent: %s | displayName: %s"), *fs_nodeUniqID, *fs_parentName, *fs_nodeDisplayName);
420429

421-
m_dagNodes.push_back(dagNode);
430+
UGameplayStatics::FinishSpawningActor(dagNode, SpawnTransform);
431+
m_dagNodes.Add(dagNode);
422432
}
423433
else
424434
{
@@ -428,31 +438,37 @@ void ASofaContext::loadNodeGraph()
428438

429439

430440
// Reorder Node using Parent
431-
for (unsigned int i = 0; i < m_dagNodes.size(); ++i)
441+
for (auto& WeakDagNode : m_dagNodes)
432442
{
433-
ASofaDAGNode* dagNode = m_dagNodes[i];
434-
const FString& parentName = dagNode->getParentName();
435-
//UE_LOG(SUnreal_log, Log, TEXT("## Process: %s | %s"), *dagNode->getUniqNameID(), *parentName);
443+
ASofaDAGNode* dagNode = WeakDagNode.Get();
444+
if (dagNode == nullptr)
445+
continue;
436446

447+
const FString& parentName = dagNode->getParentName();
437448
auto res = parentName.Compare("None");
438449
if (res == 0)
439450
continue;
440451

441-
for (unsigned int j = 0; j < m_dagNodes.size(); ++j)
452+
for (auto& WeakOther : m_dagNodes)
442453
{
443-
ASofaDAGNode* otherDagNode = m_dagNodes[j];
444-
if (otherDagNode->getUniqNameID().Compare(parentName) == 0)
454+
if (ASofaDAGNode* otherDagNode = WeakOther.Get())
445455
{
446-
dagNode->AttachToActor(otherDagNode, FAttachmentTransformRules::KeepRelativeTransform);
456+
if (otherDagNode->getUniqNameID().Compare(parentName) == 0)
457+
{
458+
dagNode->AttachToActor(otherDagNode, FAttachmentTransformRules::KeepRelativeTransform);
459+
}
447460
}
448461
}
449462
}
450463

451-
UE_LOG(SUnreal_log, Warning, TEXT("## ASofaContext::loadNodeGraph: Load all components | nbr Nodes: %d"), m_dagNodes.size());
464+
UE_LOG(SUnreal_log, Warning, TEXT("## ASofaContext::loadNodeGraph: Load all components | nbr Nodes: %d"), m_dagNodes.Num());
452465
// Load Components Graph
453-
for (unsigned int i = 0; i < m_dagNodes.size(); ++i)
466+
for (auto& WeakDagNode : m_dagNodes)
454467
{
455-
m_dagNodes[i]->loadComponents(this->m_sofaAPI);
468+
if (ASofaDAGNode* dagNode = WeakDagNode.Get())
469+
{
470+
dagNode->loadComponents(m_sofaAPI);
471+
}
456472
}
457473

458474
}
@@ -481,30 +497,36 @@ void ASofaContext::reconnectNodeGraph()
481497
}
482498
else
483499
{
484-
m_dagNodes.push_back(dagNode);
500+
m_dagNodes.Add(dagNode);
485501
}
486502
}
487503

488504
// reconnect NodeGraph
489-
for (unsigned int i = 0; i < m_dagNodes.size(); ++i)
505+
for (auto& WeakDagNode : m_dagNodes)
490506
{
491-
m_dagNodes[i]->reconnectComponents(this->m_sofaAPI);
507+
if (ASofaDAGNode* dagNode = WeakDagNode.Get())
508+
{
509+
dagNode->reconnectComponents(m_sofaAPI);
510+
}
492511
}
493512
}
494513

495514

496515
void ASofaContext::clearNodeGraph()
497516
{
498-
UE_LOG(SUnreal_log, Warning, TEXT("## ASofaContext::clearNodeGraph: Number of Node nbr: %d"), m_dagNodes.size());
517+
UE_LOG(SUnreal_log, Warning, TEXT("## ASofaContext::clearNodeGraph: Number of Node nbr: %d"), m_dagNodes.Num());
499518

500-
for (ASofaDAGNode* node : m_dagNodes)
519+
for (auto& WeakDagNode : m_dagNodes)
501520
{
502-
if (node != nullptr)
521+
if (ASofaDAGNode* Node = WeakDagNode.Get())
503522
{
504-
node->Destroy();
523+
// Optionally destroy existing actors
524+
Node->Destroy();
505525
}
506526
}
507-
m_dagNodes.clear();
527+
528+
// Clear the array
529+
m_dagNodes.Empty();
508530
}
509531

510532

Source/SofaUE5/Public/DAGNode/SofaDAGNode.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class SOFAUE5_API ASofaDAGNode : public AActor
3838
void setParentName(const FString& parentName) { m_parentName = parentName; }
3939

4040
bool loadComponents(SofaAdvancePhysicsAPI* _sofaAPI);
41-
void loadComponents();
4241
void clearComponents();
4342

4443
void reconnectComponents(SofaAdvancePhysicsAPI* _sofaAPI);
@@ -52,14 +51,6 @@ class SOFAUE5_API ASofaDAGNode : public AActor
5251
return m_uniqueNameID;
5352
}
5453

55-
#if WITH_EDITOR
56-
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
57-
#endif
58-
59-
60-
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sofa Parameters")
61-
bool ComponentLoaded = false;
62-
6354
private:
6455
SofaAdvancePhysicsAPI* m_sofaAPI = nullptr;
6556

Source/SofaUE5/Public/SofaContext.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ class SOFAUE5_API ASofaContext : public AActor
109109
UPROPERTY(SaveGame)
110110
int m_status;
111111

112-
std::vector <ASofaDAGNode*> m_dagNodes;
113-
112+
TArray<TWeakObjectPtr<ASofaDAGNode>> m_dagNodes;
114113

115114
};

0 commit comments

Comments
 (0)