3.3. Structures
This sections explains how to inspect structures in a SyncWorld
.
Structures are automatically created/deleted by the SyncWorld
when it is modified, so users can't directly edit structures. They can be inspected by getting a StructureReference
object.
Prerequisites
- Selecting a Gustave configuration
- Creating an empty World: we'll reuse the
newWorld()
function.
auto world = newWorld();
- Adding & inspecting world blocks: we'll add a few blocks for this tutorial:
// kilogram
auto const foundationMass = 10'0000.0;
auto const struct1Mass = 1'000.0;
auto const struct2Mass = 2'000.0;
auto const struct3Mass = 3'000.0;
{
auto tr = World::Transaction{};
// foundation shared between structure 1 & 2
tr.addBlock({ { 0,0,0 }, maxBlockStress, foundationMass, true });
// structure 1
tr.addBlock({ { 0,1,0 }, maxBlockStress, struct1Mass, false });
tr.addBlock({ { 0,2,0 }, maxBlockStress, struct1Mass, false });
// structure 2
tr.addBlock({ { 1,0,0 }, maxBlockStress, struct2Mass, false });
tr.addBlock({ { 2,0,0 }, maxBlockStress, struct2Mass, false });
tr.addBlock({ { 3,0,0 }, maxBlockStress, struct2Mass, false });
tr.addBlock({ { 4,0,0 }, maxBlockStress, struct2Mass, true });
// structure 3 (no foundations)
tr.addBlock({ { 7,0,0 }, maxBlockStress, struct3Mass, false });
tr.addBlock({ { 8,0,0 }, maxBlockStress, struct3Mass, false });
world.modify(tr);
}
Here's a visual representation of this world:
List all structures and their blocks
world.structures()
is a forward range of StructureReference
. You can iterate over it using a range-based for loop. Then a StructureReference
has a .blocks()
method, which works like world.blocks()
, and is a range of BlockReference
objects.
So iterating over all structures and listing their blocks is a simple double loop:
std::cout << "List of structures (size = " << world.structures().size() << ")\n";
for (auto const& structure : world.structures()) {
std::cout << "- structure of " << structure.blocks().size() << " blocks:\n";
for (auto const& block : structure.blocks()) {
std::cout << " - " << block.index() << '\n';
}
}
Note
Both world.structures()
and structure.blocks()
are unordered containers, so all structures and blocks are given in no particular order.
Possible output:
List of structures (size = 3)
- structure of 2 blocks:
- { "x": 8, "y": 0, "z": 0}
- { "x": 7, "y": 0, "z": 0}
- structure of 5 blocks:
- { "x": 4, "y": 0, "z": 0}
- { "x": 3, "y": 0, "z": 0}
- { "x": 2, "y": 0, "z": 0}
- { "x": 0, "y": 0, "z": 0}
- { "x": 1, "y": 0, "z": 0}
- structure of 3 blocks:
- { "x": 0, "y": 2, "z": 0}
- { "x": 0, "y": 0, "z": 0}
- { "x": 0, "y": 1, "z": 0}
In the above output:
- The
2 blocks
structure is the blue one on the right. - The
5 blocks
structure is the green one, and includes the 2 foundations - The
3 blocks
structure is the red one on the left, and includes the bottom-left foundation.
List all structures of a block
A BlockReference
has a .structures()
method returning a range of StructureReference
, similar to world.structures()
:
auto listStructuresOfBlock = [&world](World::BlockIndex const& blockId) -> void {
auto const blockRef = world.blocks().at(blockId);
std::cout << "Structures of block " << blockId << " (size = " << blockRef.structures().size() << "):\n";
for (auto const& structureRef : blockRef.structures()) {
std::cout << "- structure of " << structureRef.blocks().size() << " blocks\n";
}
};
listStructuresOfBlock({ 0,0,0 });
listStructuresOfBlock({ 7,0,0 });
Expected output:
Structures of block { "x": 0, "y": 0, "z": 0} (size = 2):
- structure of 5 blocks
- structure of 3 blocks
Structures of block { "x": 7, "y": 0, "z": 0} (size = 1):
- structure of 2 blocks
Note
A non-foundation block always has exactly 1 structure. A foundation block can have 0 to 6 structures in a cuboid world.
Structure status: valid and solved
A StructureReference
has two important methods about its status:
isValid()
: checks if the structure still exists in the world. Iffalse
, all other operations on this reference will throw. This can happen if aworld.modify()
call deleted the structure.isSolved()
: checks if the solver was able to find a solution. Itfalse
, it is possible get the list of blocks, links and contacts of this structure, but reading forces and stresses will throw. This can happen if a structure has no foundation (or the solver didn't converge).
Running this test code:
auto printStructureStatusOfBlock = [&world](World::BlockIndex const& blockId) -> void {
auto const structureRef = world.blocks().at(blockId).structures()[0];
std::cout << "Statut of structure of block " << blockId << ": ";
if (structureRef.isValid()) {
if (structureRef.isSolved()) {
std::cout << "solved\n";
} else {
std::cout << "not solved\n";
}
} else {
std::cout << "invalid\n";
}
};
printStructureStatusOfBlock({ 0,1,0 });
printStructureStatusOfBlock({ 7,0,0 });
Should give the following output:
Statut of structure of block { "x": 0, "y": 1, "z": 0}: solved
Statut of structure of block { "x": 7, "y": 0, "z": 0}: not solved