Skip to content

Commit

Permalink
Write resources in topological order
Browse files Browse the repository at this point in the history
  • Loading branch information
3dJan committed Oct 10, 2024
1 parent c497b86 commit 999b723
Show file tree
Hide file tree
Showing 22 changed files with 458 additions and 66 deletions.
35 changes: 22 additions & 13 deletions Include/Common/Graph/DirectedGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Copyright (C) 2023 3MF Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,276529
are permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification,276529 are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Expand Down Expand Up @@ -33,26 +34,34 @@ namespace NMR::common::graph
{
class DirectedGraph : public IDirectedGraph
{
public:
public:
explicit DirectedGraph(std::size_t size);

void addDependency(Identifier id, Identifier idOfDependency) override;
void removeDependency(Identifier id,
Identifier idOfDependency) override;
[[nodiscard]] auto isDirectlyDependingOn(
Identifier id,
Identifier dependencyInQuestion) const -> bool override;

void removeDependency(Identifier id, Identifier idOfDependency) override;
[[nodiscard]] bool isDirectlyDependingOn(Identifier id,
Identifier dependencyInQuestion) const override;

[[nodiscard]] std::size_t getSize() const override;
[[nodiscard]] auto getSize() const -> std::size_t override;

void removeVertex(Identifier id) override;

[[nodiscard]] DependencySet const & getVertices() const override;
[[nodiscard]] auto getVertices() const -> const DependencySet& override;
void addVertex(Identifier id) override;

private:
private:
std::size_t m_size;
std::vector<bool> m_graphData;

DependencySet m_vertices;
DependencySet m_vertices; // Possible performance improvement: We could
// try out a std::set

using PredecessorList = std::vector<std::size_t>;
std::vector<PredecessorList> m_predecessors;

// Inherited via IDirectedGraph
[[nodiscard]] auto hasPredecessors(Identifier id) const
-> bool override;
};
}
} // namespace NMR::common::graph
30 changes: 18 additions & 12 deletions Include/Common/Graph/IDirectedGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Copyright (C) 2023 3MF Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,276529
are permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification,276529 are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Expand Down Expand Up @@ -39,18 +40,23 @@ namespace NMR::common::graph

class IDirectedGraph
{
public:
explicit IDirectedGraph(std::size_t const /*unused*/){};
public:
explicit IDirectedGraph(std::size_t const /*unused*/) {};
virtual ~IDirectedGraph() = default;
virtual void addDependency(Identifier id, Identifier idOfDependency) = 0;
virtual void removeDependency(Identifier id, Identifier idOfDependency) = 0;
[[nodiscard]] virtual bool isDirectlyDependingOn(Identifier id,
Identifier dependencyInQuestion) const = 0;

[[nodiscard]] virtual std::size_t getSize() const = 0;
virtual void addDependency(Identifier id,
Identifier idOfDependency) = 0;
virtual void removeDependency(Identifier id,
Identifier idOfDependency) = 0;
[[nodiscard]] virtual auto isDirectlyDependingOn(
Identifier id, Identifier dependencyInQuestion) const -> bool = 0;

[[nodiscard]] virtual auto getSize() const -> std::size_t = 0;
virtual void removeVertex(Identifier id) = 0;
virtual void addVertex(Identifier id) = 0;
[[nodiscard]] virtual auto hasPredecessors(Identifier id) const
-> bool = 0;

[[nodiscard]] virtual DependencySet const & getVertices() const = 0;
[[nodiscard]] virtual auto getVertices() const
-> const DependencySet& = 0;
};
} // namespace gladius::nodes::graph
} // namespace NMR::common::graph
2 changes: 2 additions & 0 deletions Include/Model/Classes/NMR_Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ namespace NMR {
nfBool hasCryptoRandCallbak() const;
nfUint64 generateRandomBytes(nfByte *, nfUint64);

[[nodiscard]] ModelResourceID getMaxModelResourceID();

};

typedef std::shared_ptr <CModel> PModel;
Expand Down
2 changes: 2 additions & 0 deletions Include/Model/Classes/NMR_ModelComponentsObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ namespace NMR {
void calculateComponentDepthLevel(nfUint32 nLevel) override;

void extendOutbox(_Out_ NOUTBOX3& vOutBox, _In_ const NMATRIX3 mAccumulatedMatrix) override;

ResourceDependencies getDependencies() override;
};

typedef std::shared_ptr <CModelComponentsObject> PModelComponentsObject;
Expand Down
2 changes: 2 additions & 0 deletions Include/Model/Classes/NMR_ModelImplicitFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ namespace NMR
void sortNodesTopologically();

PModelImplicitPort findPort(const ImplicitIdentifier& sIdentifier) const;

ResourceDependencies getDependencies() override;
};

using PModelImplicitFunction = std::shared_ptr<CModelImplicitFunction>;
Expand Down
2 changes: 2 additions & 0 deletions Include/Model/Classes/NMR_ModelLevelSetObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ namespace NMR {

void setMeshBBoxOnly(bool bMeshBBoxOnly);
bool getMeshBBoxOnly() const;

ResourceDependencies getDependencies() override;
};

typedef std::shared_ptr <CModelLevelSetObject> PModelLevelSetObject;
Expand Down
2 changes: 2 additions & 0 deletions Include/Model/Classes/NMR_ModelMeshObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ namespace NMR {

_Ret_notnull_ PModelVolumeData getVolumeData();
void setVolumeData(_In_ PModelVolumeData pVolumeData);

ResourceDependencies getDependencies() override;
};

typedef std::shared_ptr <CModelMeshObject> PModelMeshObject;
Expand Down
1 change: 0 additions & 1 deletion Include/Model/Classes/NMR_ModelObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ namespace NMR {
virtual void calculateComponentDepthLevel (nfUint32 nLevel);

virtual void extendOutbox(_Out_ NOUTBOX3& vOutBox, _In_ const NMATRIX3 mAccumulatedMatrix) = 0;

};

typedef std::shared_ptr <CModelObject> PModelObject;
Expand Down
10 changes: 8 additions & 2 deletions Include/Model/Classes/NMR_ModelResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ resource object.
#include "Model/Classes/NMR_Model.h"

#include <string>
#include <vector>

namespace NMR {

using ResourceDependencies = std::vector<PPackageResourceID>;

class CModelResource {
private:
CModel * m_pModel;
Expand All @@ -52,8 +55,7 @@ namespace NMR {
protected:
std::vector<ModelPropertyID> m_ResourceIndexMap;
nfBool m_bHasResourceIndexMap;
CModel * Model();

CModel * Model();
public:
CModelResource() = delete;
// CModelResource(_In_ const PPackageResourceID sResourceID, _In_ CModel * pModel);
Expand All @@ -70,6 +72,10 @@ namespace NMR {

_Ret_notnull_ CModel * getModel();
void setModel(CModel * pModel);

/// Returns all dependencies of this resource, usd for topological sorting during writing
virtual ResourceDependencies getDependencies();

};

typedef std::shared_ptr <CModelResource> PModelResource;
Expand Down
4 changes: 4 additions & 0 deletions Include/Model/Classes/NMR_ModelVolumeData.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ namespace NMR {
PVolumeDataComposite createComposite(/* basematerialgroupd*/);
void setComposite(PVolumeDataComposite pComposite);
void removeComposite();

ResourceDependencies getDependencies() override;

PPackageResourceID packageResourceIDFromModelResourceID(ModelResourceID modelResourceID);
};

typedef std::shared_ptr <CModelVolumeData> PModelVolumeData;
Expand Down
65 changes: 65 additions & 0 deletions Include/Model/Writer/v100/NMR_ResourceDependencySorter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*++
Copyright (C) 2024 3MF Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Abstract:
NMR_ResourcDependencySorter resolves the dependencies between resources by
sorting them topologically.
--*/

#pragma once

#include <unordered_map>

#include "Common/Graph/DirectedGraph.h"
#include "Common/Graph/GraphAlgorithms.h"
#include "Model/Classes/NMR_Model.h"

namespace NMR
{
using TopologicalSortResult = std::vector<PPackageResourceID>;

class CResourceDependencySorter
{
private:
common::graph::DirectedGraph buildGraph();
void buildIndexMaps();

[[nodiscard]] PPackageResourceID indexToModelResourceID(size_t index) const;
[[nodiscard]] size_t modelResourceIDToIndex(PPackageResourceID resourceID) const;

CModel * m_pModel;

std::unordered_map<size_t, PPackageResourceID> m_indexToResourceID;
std::unordered_map<PPackageResourceID, size_t> m_resourceIDToIndex;

public:
explicit CResourceDependencySorter(CModel * pModel);
TopologicalSortResult sort();

};

} // namespace NMR
36 changes: 21 additions & 15 deletions Source/Common/Graph/DirectedGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ Copyright (C) 2023 3MF Consortium
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,276529
are permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification,276529 are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Expand Down Expand Up @@ -33,31 +34,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace NMR::common::graph
{
DirectedGraph::DirectedGraph(size_t const size)
: IDirectedGraph(size)
, m_size(size)
, m_graphData(m_size * m_size, false)
: IDirectedGraph(size),
m_size(size),
m_graphData((m_size + 1) * (m_size + 1), false)
{
}

void DirectedGraph::addDependency(Identifier id, Identifier idOfDependency)
{
addVertex(id);
addVertex(idOfDependency);
if (id == idOfDependency)
if(id == idOfDependency)
{
return;
}
auto const index = id * m_size + idOfDependency;
m_graphData[index] = true;
}

void DirectedGraph::removeDependency(Identifier id, Identifier idOfDependency)
void DirectedGraph::removeDependency(Identifier id,
Identifier idOfDependency)
{
auto const index = id * m_size + idOfDependency;
m_graphData[index] = false;
}

bool DirectedGraph::isDirectlyDependingOn(Identifier id, Identifier dependencyInQuestion) const
bool DirectedGraph::isDirectlyDependingOn(
Identifier id, Identifier dependencyInQuestion) const
{
auto const index = id * m_size + dependencyInQuestion;
return m_graphData[index];
Expand All @@ -70,21 +71,22 @@ namespace NMR::common::graph

void DirectedGraph::removeVertex(Identifier id)
{
auto const iterElemToRemove = std::find(std::begin(m_vertices), std::end(m_vertices), id);
if (iterElemToRemove == std::end(m_vertices))
auto const iterElemToRemove =
std::find(std::begin(m_vertices), std::end(m_vertices), id);
if(iterElemToRemove == std::end(m_vertices))
{
return;
}
m_vertices.erase(iterElemToRemove);

for (auto vertex : m_vertices)
for(auto vertex : m_vertices)
{
removeDependency(id, vertex);
removeDependency(vertex, id);
}
}

DependencySet const& DirectedGraph::getVertices() const
auto DirectedGraph::getVertices() const -> const DependencySet&
{
return m_vertices;
}
Expand All @@ -94,4 +96,8 @@ namespace NMR::common::graph
m_vertices.insert(id);
}

} // namespace gladius::nodes::graph
auto DirectedGraph::hasPredecessors(Identifier id) const -> bool
{
return !m_predecessors[id].empty();
}
} // namespace NMR::common::graph
Loading

0 comments on commit 999b723

Please sign in to comment.