From c1663f27a1b40a9c4e2d920234f979824ddf4219 Mon Sep 17 00:00:00 2001 From: "Vegard Stengrundet (Omega AS)" Date: Tue, 1 Aug 2023 14:45:37 +0200 Subject: [PATCH 01/15] Add priority options and add priorty to APrimitives --- CadRevealComposer.Exe/CommandLineOptions.cs | 14 +++ CadRevealComposer.Exe/Program.cs | 22 ++++- CadRevealComposer/CadRevealComposerRunner.cs | 13 ++- CadRevealComposer/CadRevealNode.cs | 2 + .../Configuration/ComposerParameters.cs | 8 +- .../IModelFormatProvider.cs | 3 +- .../Operations/PriorityMapping.cs | 41 +++++++++ .../Operations/SectorSplitting/Node.cs | 3 +- .../SectorSplitting/SectorSplitterOctree.cs | 4 + .../SectorSplitting/SplittingUtils.cs | 3 +- CadRevealComposer/Primitives/APrimitive.cs | 90 +++++++++++++------ .../FbxProviderTests.cs | 7 +- CadRevealFbxProvider/FbxProvider.cs | 3 +- .../ObjProviderTests.cs | 3 +- CadRevealObjProvider/ObjProvider.cs | 3 +- CadRevealRvmProvider/RvmProvider.cs | 7 +- .../RvmStoreToCadRevealNodesConverter.cs | 51 +++++++++-- 17 files changed, 230 insertions(+), 47 deletions(-) create mode 100644 CadRevealComposer/Operations/PriorityMapping.cs diff --git a/CadRevealComposer.Exe/CommandLineOptions.cs b/CadRevealComposer.Exe/CommandLineOptions.cs index 456a0ec57..bfef181f9 100644 --- a/CadRevealComposer.Exe/CommandLineOptions.cs +++ b/CadRevealComposer.Exe/CommandLineOptions.cs @@ -78,6 +78,20 @@ public class CommandLineOptions )] public string? NodeNameExcludeRegex { get; init; } = null; + [Option( + longName: "PrioritizedDiscipline", + Required = false, + HelpText = "A regex matching disciplines to be prioritized in sector splitting. Not case sensitive." + )] + public string? PrioritizedDisciplineRegex { get; init; } = null; + + [Option( + longName: "PrioritizedNodeName", + Required = false, + HelpText = "A regex matching node names to be prioritized in sector splitting. Not case sensitive." + )] + public string? PrioritizedNodeNameRegex { get; init; } = null; + [Option(longName: "SplitIntoZones", shortName: 'z', Required = false, HelpText = "Split models into zones.")] public bool SplitIntoZones { get; init; } diff --git a/CadRevealComposer.Exe/Program.cs b/CadRevealComposer.Exe/Program.cs index e9b332eb8..0ed40e94e 100644 --- a/CadRevealComposer.Exe/Program.cs +++ b/CadRevealComposer.Exe/Program.cs @@ -58,11 +58,31 @@ private static int RunOptionsAndReturnExitCode(CommandLineOptions options) ); } + if (options.PrioritizedDisciplineRegex != null) + { // Ensure regex is valid. + if (!RegexUtils.IsValidRegex(options.PrioritizedDisciplineRegex)) + throw new ArgumentException( + $"The {nameof(options.PrioritizedDisciplineRegex)} is not a valid regex. Check its syntax. " + + $"The input was: {options.PrioritizedDisciplineRegex}" + ); + } + + if (options.PrioritizedNodeNameRegex != null) + { // Ensure regex is valid. + if (!RegexUtils.IsValidRegex(options.PrioritizedNodeNameRegex)) + throw new ArgumentException( + $"The {nameof(options.PrioritizedNodeNameRegex)} is not a valid regex. Check its syntax. " + + $"The input was: {options.PrioritizedNodeNameRegex}" + ); + } + var toolsParameters = new ComposerParameters( options.NoInstancing, options.SingleSector, options.SplitIntoZones, - new NodeNameExcludeRegex(options.NodeNameExcludeRegex) + new NodeNameExcludeRegex(options.NodeNameExcludeRegex), + new PrioritizedDisciplinesRegex(options.PrioritizedDisciplineRegex), + new PrioritizedNodeNamesRegex(options.PrioritizedNodeNameRegex) ); if (options.SplitIntoZones) diff --git a/CadRevealComposer/CadRevealComposerRunner.cs b/CadRevealComposer/CadRevealComposerRunner.cs index 167013555..1f23c4281 100644 --- a/CadRevealComposer/CadRevealComposerRunner.cs +++ b/CadRevealComposer/CadRevealComposerRunner.cs @@ -36,6 +36,10 @@ IReadOnlyList modelFormatProviders var instanceIdGenerator = new InstanceIdGenerator(); var filtering = new NodeNameFiltering(composerParameters.NodeNameExcludeRegex); + var nodePriorityFiltering = new PriorityMapping( + composerParameters.PrioritizedDisciplinesRegex, + composerParameters.PrioritizedNodeNamesRegex + ); // TODO: Add in composerParameters foreach (IModelFormatProvider modelFormatProvider in modelFormatProviders) { @@ -44,7 +48,8 @@ IReadOnlyList modelFormatProviders inputFolderPath.EnumerateFiles(), treeIndexGenerator, instanceIdGenerator, - filtering + filtering, + nodePriorityFiltering ); Console.WriteLine( @@ -56,7 +61,11 @@ IReadOnlyList modelFormatProviders // collect all nodes for later sector division of the entire scene nodesToExport.AddRange(cadRevealNodes); - var inputGeometries = cadRevealNodes.AsParallel().AsOrdered().SelectMany(x => x.Geometries).ToArray(); + var inputGeometries = cadRevealNodes + .AsParallel() + .AsOrdered() + .SelectMany(node => node.Geometries) + .ToArray(); var geometriesIncludingMeshes = modelFormatProvider.ProcessGeometries( inputGeometries, diff --git a/CadRevealComposer/CadRevealNode.cs b/CadRevealComposer/CadRevealNode.cs index 36298a711..e8e2d6f0c 100644 --- a/CadRevealComposer/CadRevealNode.cs +++ b/CadRevealComposer/CadRevealNode.cs @@ -1,5 +1,6 @@ namespace CadRevealComposer; +using Operations; using Primitives; using System; using System.Collections.Generic; @@ -46,6 +47,7 @@ public class CadRevealNode public Dictionary Attributes = new Dictionary(); public required CadRevealNode? Parent; public CadRevealNode[]? Children; + public NodePriority Priority; public APrimitive[] Geometries = Array.Empty(); diff --git a/CadRevealComposer/Configuration/ComposerParameters.cs b/CadRevealComposer/Configuration/ComposerParameters.cs index 2c97d1443..a32632af9 100644 --- a/CadRevealComposer/Configuration/ComposerParameters.cs +++ b/CadRevealComposer/Configuration/ComposerParameters.cs @@ -4,7 +4,13 @@ public record ComposerParameters( bool NoInstancing, bool SingleSector, bool SplitIntoZones, - NodeNameExcludeRegex NodeNameExcludeRegex + NodeNameExcludeRegex NodeNameExcludeRegex, + PrioritizedDisciplinesRegex PrioritizedDisciplinesRegex, + PrioritizedNodeNamesRegex PrioritizedNodeNamesRegex ); public record NodeNameExcludeRegex(string? Value); + +public record PrioritizedDisciplinesRegex(string? Value); + +public record PrioritizedNodeNamesRegex(string? Value); diff --git a/CadRevealComposer/ModelFormatProvider/IModelFormatProvider.cs b/CadRevealComposer/ModelFormatProvider/IModelFormatProvider.cs index e26c29bab..066286f10 100644 --- a/CadRevealComposer/ModelFormatProvider/IModelFormatProvider.cs +++ b/CadRevealComposer/ModelFormatProvider/IModelFormatProvider.cs @@ -13,7 +13,8 @@ IReadOnlyList ParseFiles( IEnumerable filesToParse, TreeIndexGenerator treeIndexGenerator, InstanceIdGenerator instanceIdGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ); public APrimitive[] ProcessGeometries( diff --git a/CadRevealComposer/Operations/PriorityMapping.cs b/CadRevealComposer/Operations/PriorityMapping.cs new file mode 100644 index 000000000..5522cf924 --- /dev/null +++ b/CadRevealComposer/Operations/PriorityMapping.cs @@ -0,0 +1,41 @@ +namespace CadRevealComposer.Operations; + +using Configuration; +using System.Text.RegularExpressions; + +public enum NodePriority +{ + High, + Medium, + Default +} + +public class PriorityMapping +{ + private readonly Regex? _disciplineRegex; // + private readonly Regex? _nodeNameRegex; + + public PriorityMapping(PrioritizedDisciplinesRegex disciplineRegex, PrioritizedNodeNamesRegex nodeNameRegex) + { + if (disciplineRegex.Value != null) + { + _disciplineRegex = new Regex(disciplineRegex.Value, RegexOptions.IgnoreCase); + } + + if (nodeNameRegex.Value != null) + { + _nodeNameRegex = new Regex(nodeNameRegex.Value, RegexOptions.IgnoreCase); + } + } + + public NodePriority GetPriority(string discipline, string nodeName) + { + if (_nodeNameRegex != null && _nodeNameRegex.IsMatch(nodeName)) + return NodePriority.High; + + if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) + return NodePriority.Medium; + + return NodePriority.Default; + } +} diff --git a/CadRevealComposer/Operations/SectorSplitting/Node.cs b/CadRevealComposer/Operations/SectorSplitting/Node.cs index 871657dc8..ff79cfc16 100644 --- a/CadRevealComposer/Operations/SectorSplitting/Node.cs +++ b/CadRevealComposer/Operations/SectorSplitting/Node.cs @@ -7,7 +7,8 @@ public record Node( APrimitive[] Geometries, long EstimatedByteSize, long EstimatedTriangleCount, - BoundingBox BoundingBox + BoundingBox BoundingBox, + NodePriority Priority ) { public float Diagonal => BoundingBox.Diagonal; diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index c2d046ed9..2ed04e938 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -22,6 +22,10 @@ public IEnumerable SplitIntoSectors(APrimitive[] allGeometries) var sectorIdGenerator = new SequentialIdGenerator(); var allNodes = SplittingUtils.ConvertPrimitivesToNodes(allGeometries); + + var mediumPrioritizedNodes = allNodes.Where(x => x.Priority == NodePriority.Medium).ToArray(); + var highPrioritizedNodes = allNodes.Where(x => x.Priority == NodePriority.High).ToArray(); + var (regularNodes, outlierNodes) = allNodes.SplitNodesIntoRegularAndOutlierNodes(0.995f); var boundingBoxEncapsulatingAllNodes = allNodes.CalculateBoundingBox(); var boundingBoxEncapsulatingMostNodes = regularNodes.CalculateBoundingBox(); diff --git a/CadRevealComposer/Operations/SectorSplitting/SplittingUtils.cs b/CadRevealComposer/Operations/SectorSplitting/SplittingUtils.cs index 07487711d..876d7cda1 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SplittingUtils.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SplittingUtils.cs @@ -167,7 +167,8 @@ public static Node[] ConvertPrimitivesToNodes(APrimitive[] primitives) geometries, geometries.Sum(DrawCallEstimator.EstimateByteSize), EstimatedTriangleCount: DrawCallEstimator.Estimate(geometries).EstimatedTriangleCount, - boundingBox + boundingBox, + g.NodePriority ); }) .ToArray(); diff --git a/CadRevealComposer/Primitives/APrimitive.cs b/CadRevealComposer/Primitives/APrimitive.cs index abaf08972..4122aeea9 100644 --- a/CadRevealComposer/Primitives/APrimitive.cs +++ b/CadRevealComposer/Primitives/APrimitive.cs @@ -1,20 +1,28 @@ namespace CadRevealComposer.Primitives; +using Operations; +using Operations.SectorSplitting; using System.Drawing; using System.Numerics; using Tessellation; // Reveal GLTF model -public sealed record Box(Matrix4x4 InstanceMatrix, ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox) - : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); +public sealed record Box( + Matrix4x4 InstanceMatrix, + ulong TreeIndex, + Color Color, + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record Circle( Matrix4x4 InstanceMatrix, Vector3 Normal, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record Cone( float Angle, @@ -26,8 +34,9 @@ public sealed record Cone( float RadiusB, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record EccentricCone( Vector3 CenterA, @@ -37,8 +46,9 @@ public sealed record EccentricCone( float RadiusB, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record EllipsoidSegment( float HorizontalRadius, @@ -48,8 +58,9 @@ public sealed record EllipsoidSegment( Vector3 Normal, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record GeneralCylinder( float Angle, @@ -62,8 +73,9 @@ public sealed record GeneralCylinder( float Radius, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record GeneralRing( float Angle, @@ -73,14 +85,25 @@ public sealed record GeneralRing( float Thickness, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); -public sealed record Nut(Matrix4x4 InstanceMatrix, ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox) - : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); +public sealed record Nut( + Matrix4x4 InstanceMatrix, + ulong TreeIndex, + Color Color, + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); -public sealed record Quad(Matrix4x4 InstanceMatrix, ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox) - : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); +public sealed record Quad( + Matrix4x4 InstanceMatrix, + ulong TreeIndex, + Color Color, + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record TorusSegment( float ArcAngle, @@ -89,8 +112,9 @@ public sealed record TorusSegment( float TubeRadius, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); public sealed record Trapezium( Vector3 Vertex1, @@ -99,8 +123,9 @@ public sealed record Trapezium( Vector3 Vertex4, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); /// /// Defines an "Instance" of a Template. A instance that shares a Geometry representation with other instances of a shared "Template" reference. @@ -119,10 +144,21 @@ public sealed record InstancedMesh( Matrix4x4 InstanceMatrix, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); -public sealed record TriangleMesh(Mesh Mesh, ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox) - : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); +public sealed record TriangleMesh( + Mesh Mesh, + ulong TreeIndex, + Color Color, + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, NodePriority); -public abstract record APrimitive(ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox); +public abstract record APrimitive( + ulong TreeIndex, + Color Color, + BoundingBox AxisAlignedBoundingBox, + NodePriority NodePriority = NodePriority.Default +); diff --git a/CadRevealFbxProvider.Tests/FbxProviderTests.cs b/CadRevealFbxProvider.Tests/FbxProviderTests.cs index 89fc6a3ae..d81bc8973 100644 --- a/CadRevealFbxProvider.Tests/FbxProviderTests.cs +++ b/CadRevealFbxProvider.Tests/FbxProviderTests.cs @@ -32,7 +32,9 @@ public class FbxProviderTests false, true, false, - new NodeNameExcludeRegex(null) + new NodeNameExcludeRegex(null), + new PrioritizedDisciplinesRegex(null), + new PrioritizedNodeNamesRegex(null) ); private static readonly List providers = new List() @@ -141,7 +143,8 @@ public void SampleModel_AttributeTest() inputDirectoryCorrect.EnumerateFiles(), treeIndexGenerator, instanceIndexGenerator, - new NodeNameFiltering(new NodeNameExcludeRegex(null)) + new NodeNameFiltering(new NodeNameExcludeRegex(null)), + new PriorityMapping(new PrioritizedDisciplinesRegex(null), new PrioritizedNodeNamesRegex(null)) ); Assert.That(nodes, Has.Count.EqualTo(28)); diff --git a/CadRevealFbxProvider/FbxProvider.cs b/CadRevealFbxProvider/FbxProvider.cs index 5e1f46177..ce0615c46 100644 --- a/CadRevealFbxProvider/FbxProvider.cs +++ b/CadRevealFbxProvider/FbxProvider.cs @@ -18,7 +18,8 @@ public IReadOnlyList ParseFiles( IEnumerable filesToParse, TreeIndexGenerator treeIndexGenerator, InstanceIdGenerator instanceIdGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ) { var workload = FbxWorkload.CollectWorkload(filesToParse.Select(x => x.FullName).ToArray()); diff --git a/CadRevealObjProvider.Tests/ObjProviderTests.cs b/CadRevealObjProvider.Tests/ObjProviderTests.cs index bfff8fca5..c09467799 100644 --- a/CadRevealObjProvider.Tests/ObjProviderTests.cs +++ b/CadRevealObjProvider.Tests/ObjProviderTests.cs @@ -20,7 +20,8 @@ public void ObjProviderTests_SmokeTest() new[] { new FileInfo("TestData/HDA_subset.obj") }, treeIndexGenerator, instanceIdGenerator, - new NodeNameFiltering(new NodeNameExcludeRegex(null)) + new NodeNameFiltering(new NodeNameExcludeRegex(null)), + new PriorityMapping(new PrioritizedDisciplinesRegex(null), new PrioritizedNodeNamesRegex(null)) ); } } diff --git a/CadRevealObjProvider/ObjProvider.cs b/CadRevealObjProvider/ObjProvider.cs index 96afb6f88..61745c5a3 100644 --- a/CadRevealObjProvider/ObjProvider.cs +++ b/CadRevealObjProvider/ObjProvider.cs @@ -19,7 +19,8 @@ public IReadOnlyList ParseFiles( IEnumerable filesToParse, TreeIndexGenerator treeIndexGenerator, InstanceIdGenerator instanceIdGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ) { var objLoaderFactory = new ObjLoaderFactory(); diff --git a/CadRevealRvmProvider/RvmProvider.cs b/CadRevealRvmProvider/RvmProvider.cs index 723e0bf2d..602a974e4 100644 --- a/CadRevealRvmProvider/RvmProvider.cs +++ b/CadRevealRvmProvider/RvmProvider.cs @@ -7,6 +7,7 @@ using CadRevealComposer.IdProviders; using CadRevealComposer.ModelFormatProvider; using CadRevealComposer.Operations; +using CadRevealComposer.Operations.SectorSplitting; using CadRevealComposer.Primitives; using CadRevealComposer.Utils; using Commons; @@ -22,7 +23,8 @@ public IReadOnlyList ParseFiles( IEnumerable filesToParse, TreeIndexGenerator treeIndexGenerator, InstanceIdGenerator instanceIdGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ) { var workload = RvmWorkload.CollectWorkload(filesToParse.Select(x => x.FullName).ToArray()); @@ -54,7 +56,8 @@ NodeNameFiltering nodeNameFiltering var nodes = RvmStoreToCadRevealNodesConverter.RvmStoreToCadRevealNodes( rvmStore, treeIndexGenerator, - nodeNameFiltering + nodeNameFiltering, + priorityMapping ); Console.WriteLine($"Converted to reveal nodes in {stopwatch.Elapsed}"); diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index 0652a1449..5ac57eb21 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -3,22 +3,34 @@ namespace CadRevealRvmProvider.Converters; using CadRevealComposer; using CadRevealComposer.IdProviders; using CadRevealComposer.Operations; +using CadRevealComposer.Primitives; using CadRevealComposer.Utils; using RvmSharp.Containers; using RvmSharp.Primitives; using System.Diagnostics; +using System.Drawing; internal static class RvmStoreToCadRevealNodesConverter { public static CadRevealNode[] RvmStoreToCadRevealNodes( RvmStore rvmStore, TreeIndexGenerator treeIndexGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ) { var cadRevealRootNodes = rvmStore.RvmFiles .SelectMany(f => f.Model.Children) - .Select(root => CollectGeometryNodesRecursive(root, parent: null, treeIndexGenerator, nodeNameFiltering)) + .Select( + root => + CollectGeometryNodesRecursive( + root, + parent: null, + treeIndexGenerator, + nodeNameFiltering, + priorityMapping + ) + ) .WhereNotNull() .ToArray(); @@ -38,7 +50,8 @@ NodeNameFiltering nodeNameFiltering RvmNode root, CadRevealNode? parent, TreeIndexGenerator treeIndexGenerator, - NodeNameFiltering nodeNameFiltering + NodeNameFiltering nodeNameFiltering, + PriorityMapping priorityMapping ) { if (nodeNameFiltering.ShouldExcludeNode(root.Name)) @@ -71,14 +84,16 @@ NodeNameFiltering nodeNameFiltering }, newNode, treeIndexGenerator, - nodeNameFiltering + nodeNameFiltering, + priorityMapping ); case RvmNode rvmNode: return CollectGeometryNodesRecursive( rvmNode, newNode, treeIndexGenerator, - nodeNameFiltering + nodeNameFiltering, + priorityMapping ); default: throw new Exception(); @@ -91,7 +106,16 @@ NodeNameFiltering nodeNameFiltering { childrenCadNodes = root.Children .OfType() - .Select(n => CollectGeometryNodesRecursive(n, newNode, treeIndexGenerator, nodeNameFiltering)) + .Select( + n => + CollectGeometryNodesRecursive( + n, + newNode, + treeIndexGenerator, + nodeNameFiltering, + priorityMapping + ) + ) .WhereNotNull() .ToArray(); rvmGeometries = root.Children.OfType().ToArray(); @@ -115,6 +139,21 @@ NodeNameFiltering nodeNameFiltering ? primitiveAndChildrenBoundingBoxes.Aggregate((a, b) => a.Encapsulate(b)) : null; + if (newNode.Attributes.Count > 0) + { + var discipline = newNode.Attributes["Discipline"]; + var name = newNode.Name; + var priority = priorityMapping.GetPriority(discipline, name); + + var geometriesWithPriority = new List(); + foreach (var geometry in newNode.Geometries) + { + geometriesWithPriority.Add(geometry with { NodePriority = priority }); + } + + newNode.Geometries = geometriesWithPriority.ToArray(); + } + return newNode; } } From a002e8488de46fa06dc73370ee8d02b778718cba Mon Sep 17 00:00:00 2001 From: "Vegard Stengrundet (Omega AS)" Date: Tue, 1 Aug 2023 15:44:53 +0200 Subject: [PATCH 02/15] Crudely push prioritized up in depth --- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 2ed04e938..05fbe8fad 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -23,9 +23,6 @@ public IEnumerable SplitIntoSectors(APrimitive[] allGeometries) var allNodes = SplittingUtils.ConvertPrimitivesToNodes(allGeometries); - var mediumPrioritizedNodes = allNodes.Where(x => x.Priority == NodePriority.Medium).ToArray(); - var highPrioritizedNodes = allNodes.Where(x => x.Priority == NodePriority.High).ToArray(); - var (regularNodes, outlierNodes) = allNodes.SplitNodesIntoRegularAndOutlierNodes(0.995f); var boundingBoxEncapsulatingAllNodes = allNodes.CalculateBoundingBox(); var boundingBoxEncapsulatingMostNodes = regularNodes.CalculateBoundingBox(); @@ -283,8 +280,11 @@ private static IEnumerable GetNodesByBudget(IReadOnlyList nodes, lon { var selectedNodes = actualDepth switch { - 1 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_1).ToArray(), - 2 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_2).ToArray(), + 1 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_1 || x.Priority == NodePriority.High).ToArray(), + 2 + => nodes + .Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_2 || x.Priority == NodePriority.Medium) + .ToArray(), 3 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_3).ToArray(), _ => nodes.ToArray(), }; From a76e65d3a3337d326776515ee977af34599bc431 Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 9 Aug 2023 13:10:50 +0200 Subject: [PATCH 03/15] Create a pri sector with highly prioritized nodes --- CadRevealComposer/CadRevealComposerRunner.cs | 8 +++- .../SectorSplitting/InternalSector.cs | 3 +- .../SectorSplitting/SectorSplitterOctree.cs | 42 ++++++++++++++++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/CadRevealComposer/CadRevealComposerRunner.cs b/CadRevealComposer/CadRevealComposerRunner.cs index 1f23c4281..aa255bdb7 100644 --- a/CadRevealComposer/CadRevealComposerRunner.cs +++ b/CadRevealComposer/CadRevealComposerRunner.cs @@ -229,9 +229,15 @@ private static void PrintSectorStats(ImmutableArray sec private static SceneCreator.SectorInfo SerializeSector(InternalSector p, string outputDirectory) { + var sectorFilename = p.Geometries.Any() ? $"sector_{p.SectorId}.glb" : null; + + if (p.Prioritized) + { + sectorFilename = $"pri_{sectorFilename}"; + } + var (estimatedTriangleCount, estimatedDrawCalls) = DrawCallEstimator.Estimate(p.Geometries); - var sectorFilename = p.Geometries.Any() ? $"sector_{p.SectorId}.glb" : null; var sectorInfo = new SceneCreator.SectorInfo( SectorId: p.SectorId, ParentSectorId: p.ParentSectorId, diff --git a/CadRevealComposer/Operations/SectorSplitting/InternalSector.cs b/CadRevealComposer/Operations/SectorSplitting/InternalSector.cs index 4fee2d617..9c8b0b8c8 100644 --- a/CadRevealComposer/Operations/SectorSplitting/InternalSector.cs +++ b/CadRevealComposer/Operations/SectorSplitting/InternalSector.cs @@ -11,5 +11,6 @@ public record InternalSector( float MaxNodeDiagonal, APrimitive[] Geometries, BoundingBox SubtreeBoundingBox, - BoundingBox? GeometryBoundingBox + BoundingBox? GeometryBoundingBox, + bool Prioritized = false ); diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 05fbe8fad..8e8b8bfc6 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -22,16 +22,25 @@ public IEnumerable SplitIntoSectors(APrimitive[] allGeometries) var sectorIdGenerator = new SequentialIdGenerator(); var allNodes = SplittingUtils.ConvertPrimitivesToNodes(allGeometries); + var highlyPrioritizedNodes = allNodes.Where(x => x.Priority == NodePriority.High).ToArray(); + var nodes = allNodes.Except(highlyPrioritizedNodes).ToArray(); - var (regularNodes, outlierNodes) = allNodes.SplitNodesIntoRegularAndOutlierNodes(0.995f); + var (regularNodes, outlierNodes) = nodes.SplitNodesIntoRegularAndOutlierNodes(0.995f); var boundingBoxEncapsulatingAllNodes = allNodes.CalculateBoundingBox(); var boundingBoxEncapsulatingMostNodes = regularNodes.CalculateBoundingBox(); var rootSectorId = (uint)sectorIdGenerator.GetNextId(); var rootPath = "/0"; + var prioritizedSectorId = (uint)sectorIdGenerator.GetNextId(); + yield return CreateRootSector(rootSectorId, rootPath, boundingBoxEncapsulatingAllNodes); + if (highlyPrioritizedNodes.Any()) + { + yield return CreatePrioritizedSectors(prioritizedSectorId, rootSectorId, highlyPrioritizedNodes, rootPath); + } + //Order nodes by diagonal size var sortedNodes = regularNodes.OrderByDescending(n => n.Diagonal).ToArray(); @@ -218,6 +227,37 @@ private InternalSector CreateRootSector(uint sectorId, string path, BoundingBox return new InternalSector(sectorId, null, 0, path, 0, 0, Array.Empty(), subtreeBoundingBox, null); } + private InternalSector CreatePrioritizedSectors( + uint prioritizedSectorId, + uint parentSectorId, + Node[] highlyPrioritizedNodes, + string rootPath + ) + { + // TODO: Currently creates one (or zero) sector + var path = $"{rootPath}/{prioritizedSectorId}"; + + var minDiagonal = highlyPrioritizedNodes.Any() ? highlyPrioritizedNodes.Min(n => n.Diagonal) : 0; + var maxDiagonal = highlyPrioritizedNodes.Any() ? highlyPrioritizedNodes.Max(n => n.Diagonal) : 0; + var geometries = highlyPrioritizedNodes.SelectMany(n => n.Geometries).ToArray(); + var geometryBoundingBox = geometries.CalculateBoundingBox(); + + var subtreeBoundingBox = highlyPrioritizedNodes.CalculateBoundingBox(); + + return new InternalSector( + prioritizedSectorId, + parentSectorId, + 1, + path, + minDiagonal, + maxDiagonal, + geometries, + subtreeBoundingBox, + geometryBoundingBox, + true + ); + } + private InternalSector CreateSector( Node[] nodes, uint sectorId, From e80187b674a314cd0de419428e956f53529fb003 Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 9 Aug 2023 14:04:10 +0200 Subject: [PATCH 04/15] Cleanup --- CadRevealComposer/CadRevealComposerRunner.cs | 4 ++-- CadRevealComposer/Operations/PriorityMapping.cs | 2 +- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CadRevealComposer/CadRevealComposerRunner.cs b/CadRevealComposer/CadRevealComposerRunner.cs index aa255bdb7..2909e8013 100644 --- a/CadRevealComposer/CadRevealComposerRunner.cs +++ b/CadRevealComposer/CadRevealComposerRunner.cs @@ -39,7 +39,7 @@ IReadOnlyList modelFormatProviders var nodePriorityFiltering = new PriorityMapping( composerParameters.PrioritizedDisciplinesRegex, composerParameters.PrioritizedNodeNamesRegex - ); // TODO: Add in composerParameters + ); foreach (IModelFormatProvider modelFormatProvider in modelFormatProviders) { @@ -231,7 +231,7 @@ private static SceneCreator.SectorInfo SerializeSector(InternalSector p, string { var sectorFilename = p.Geometries.Any() ? $"sector_{p.SectorId}.glb" : null; - if (p.Prioritized) + if (p.Prioritized && sectorFilename != null) { sectorFilename = $"pri_{sectorFilename}"; } diff --git a/CadRevealComposer/Operations/PriorityMapping.cs b/CadRevealComposer/Operations/PriorityMapping.cs index 5522cf924..3a5496fa3 100644 --- a/CadRevealComposer/Operations/PriorityMapping.cs +++ b/CadRevealComposer/Operations/PriorityMapping.cs @@ -12,7 +12,7 @@ public enum NodePriority public class PriorityMapping { - private readonly Regex? _disciplineRegex; // + private readonly Regex? _disciplineRegex; private readonly Regex? _nodeNameRegex; public PriorityMapping(PrioritizedDisciplinesRegex disciplineRegex, PrioritizedNodeNamesRegex nodeNameRegex) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 8e8b8bfc6..7f5d8c332 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -234,7 +234,7 @@ private InternalSector CreatePrioritizedSectors( string rootPath ) { - // TODO: Currently creates one (or zero) sector + // TODO: Currently creates one (or zero) sector(s) var path = $"{rootPath}/{prioritizedSectorId}"; var minDiagonal = highlyPrioritizedNodes.Any() ? highlyPrioritizedNodes.Min(n => n.Diagonal) : 0; @@ -320,7 +320,7 @@ private static IEnumerable GetNodesByBudget(IReadOnlyList nodes, lon { var selectedNodes = actualDepth switch { - 1 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_1 || x.Priority == NodePriority.High).ToArray(), + 1 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_1).ToArray(), 2 => nodes .Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_2 || x.Priority == NodePriority.Medium) From fee620c4f0717ab5cceac77f090ef647ac7ec7f0 Mon Sep 17 00:00:00 2001 From: "Vegard Stengrundet (Omega AS)" Date: Thu, 7 Sep 2023 15:29:38 +0200 Subject: [PATCH 05/15] Set priority on all children of root node --- CadRevealComposer.Exe/CommandLineOptions.cs | 7 ++++ CadRevealComposer.Exe/Program.cs | 10 ++++++ .../Operations/CameraPositioningTests.cs | 2 +- CadRevealComposer/CadRevealComposerRunner.cs | 1 + CadRevealComposer/CadRevealNode.cs | 3 +- .../Configuration/ComposerParameters.cs | 3 ++ .../Operations/PriorityMapping.cs | 23 ++++++++++--- .../SectorSplitting/SectorSplitterOctree.cs | 19 ++++++++--- .../SectorSplitting/TooFewInstancesHandler.cs | 3 +- CadRevealComposer/Primitives/APrimitive.cs | 2 +- .../FbxProviderTests.cs | 7 +++- .../ObjProviderTests.cs | 6 +++- .../RvmPyramidInstancerTests.cs | 33 ++++++++++++++++--- .../Converters/RvmFacetGroupConverter.cs | 4 ++- .../Converters/RvmPyramidConverter.cs | 4 ++- CadRevealRvmProvider/RvmProtoMesh.cs | 17 ++++++---- .../RvmStoreToCadRevealNodesConverter.cs | 26 +++++++-------- .../Tessellation/RvmTessellator.cs | 11 +++++-- 18 files changed, 136 insertions(+), 45 deletions(-) diff --git a/CadRevealComposer.Exe/CommandLineOptions.cs b/CadRevealComposer.Exe/CommandLineOptions.cs index bfef181f9..a8c7ca3ab 100644 --- a/CadRevealComposer.Exe/CommandLineOptions.cs +++ b/CadRevealComposer.Exe/CommandLineOptions.cs @@ -85,6 +85,13 @@ public class CommandLineOptions )] public string? PrioritizedDisciplineRegex { get; init; } = null; + [Option( + longName: "LowPrioritizedDiscipline", + Required = false, + HelpText = "A regex matching disciplines to be prioritized lower in sector splitting. Not case sensitive." + )] + public string? LowPrioritizedDisciplineRegex { get; init; } = null; + [Option( longName: "PrioritizedNodeName", Required = false, diff --git a/CadRevealComposer.Exe/Program.cs b/CadRevealComposer.Exe/Program.cs index 0ed40e94e..f89c6128e 100644 --- a/CadRevealComposer.Exe/Program.cs +++ b/CadRevealComposer.Exe/Program.cs @@ -67,6 +67,15 @@ private static int RunOptionsAndReturnExitCode(CommandLineOptions options) ); } + if (options.LowPrioritizedDisciplineRegex != null) + { // Ensure regex is valid. + if (!RegexUtils.IsValidRegex(options.LowPrioritizedDisciplineRegex)) + throw new ArgumentException( + $"The {nameof(options.LowPrioritizedDisciplineRegex)} is not a valid regex. Check its syntax. " + + $"The input was: {options.LowPrioritizedDisciplineRegex}" + ); + } + if (options.PrioritizedNodeNameRegex != null) { // Ensure regex is valid. if (!RegexUtils.IsValidRegex(options.PrioritizedNodeNameRegex)) @@ -82,6 +91,7 @@ private static int RunOptionsAndReturnExitCode(CommandLineOptions options) options.SplitIntoZones, new NodeNameExcludeRegex(options.NodeNameExcludeRegex), new PrioritizedDisciplinesRegex(options.PrioritizedDisciplineRegex), + new LowPrioritizedDisciplineRegex(options.LowPrioritizedDisciplineRegex), new PrioritizedNodeNamesRegex(options.PrioritizedNodeNameRegex) ); diff --git a/CadRevealComposer.Tests/Operations/CameraPositioningTests.cs b/CadRevealComposer.Tests/Operations/CameraPositioningTests.cs index 362cc9246..983b91a19 100644 --- a/CadRevealComposer.Tests/Operations/CameraPositioningTests.cs +++ b/CadRevealComposer.Tests/Operations/CameraPositioningTests.cs @@ -31,5 +31,5 @@ public void InitialCameraPositionLongestAxisY() } private record TestPrimitiveWithBoundingBox(Vector3 Min, Vector3 Max) - : APrimitive(int.MaxValue, Color.Red, new BoundingBox(Min, Max)); + : APrimitive(int.MaxValue, Color.Red, new BoundingBox(Min, Max), NodePriority.Default); } diff --git a/CadRevealComposer/CadRevealComposerRunner.cs b/CadRevealComposer/CadRevealComposerRunner.cs index 2909e8013..12355044f 100644 --- a/CadRevealComposer/CadRevealComposerRunner.cs +++ b/CadRevealComposer/CadRevealComposerRunner.cs @@ -38,6 +38,7 @@ IReadOnlyList modelFormatProviders var filtering = new NodeNameFiltering(composerParameters.NodeNameExcludeRegex); var nodePriorityFiltering = new PriorityMapping( composerParameters.PrioritizedDisciplinesRegex, + composerParameters.LowPrioritizedDisciplineRegex, composerParameters.PrioritizedNodeNamesRegex ); diff --git a/CadRevealComposer/CadRevealNode.cs b/CadRevealComposer/CadRevealNode.cs index e8e2d6f0c..16300d5dc 100644 --- a/CadRevealComposer/CadRevealNode.cs +++ b/CadRevealComposer/CadRevealNode.cs @@ -1,6 +1,7 @@ namespace CadRevealComposer; using Operations; +using Operations.SectorSplitting; using Primitives; using System; using System.Collections.Generic; @@ -47,8 +48,6 @@ public class CadRevealNode public Dictionary Attributes = new Dictionary(); public required CadRevealNode? Parent; public CadRevealNode[]? Children; - public NodePriority Priority; - public APrimitive[] Geometries = Array.Empty(); /// diff --git a/CadRevealComposer/Configuration/ComposerParameters.cs b/CadRevealComposer/Configuration/ComposerParameters.cs index a32632af9..dcf6fe6cb 100644 --- a/CadRevealComposer/Configuration/ComposerParameters.cs +++ b/CadRevealComposer/Configuration/ComposerParameters.cs @@ -6,6 +6,7 @@ public record ComposerParameters( bool SplitIntoZones, NodeNameExcludeRegex NodeNameExcludeRegex, PrioritizedDisciplinesRegex PrioritizedDisciplinesRegex, + LowPrioritizedDisciplineRegex LowPrioritizedDisciplineRegex, PrioritizedNodeNamesRegex PrioritizedNodeNamesRegex ); @@ -13,4 +14,6 @@ public record NodeNameExcludeRegex(string? Value); public record PrioritizedDisciplinesRegex(string? Value); +public record LowPrioritizedDisciplineRegex(string? Value); + public record PrioritizedNodeNamesRegex(string? Value); diff --git a/CadRevealComposer/Operations/PriorityMapping.cs b/CadRevealComposer/Operations/PriorityMapping.cs index 3a5496fa3..a3690f46b 100644 --- a/CadRevealComposer/Operations/PriorityMapping.cs +++ b/CadRevealComposer/Operations/PriorityMapping.cs @@ -7,35 +7,50 @@ public enum NodePriority { High, Medium, + Low, // Less than default Default } public class PriorityMapping { private readonly Regex? _disciplineRegex; + private readonly Regex? _lowDisciplineRegex; private readonly Regex? _nodeNameRegex; - public PriorityMapping(PrioritizedDisciplinesRegex disciplineRegex, PrioritizedNodeNamesRegex nodeNameRegex) + public PriorityMapping( + PrioritizedDisciplinesRegex disciplineRegex, + LowPrioritizedDisciplineRegex lowDisciplineRegex, + PrioritizedNodeNamesRegex nodeNameRegex + ) { if (disciplineRegex.Value != null) { _disciplineRegex = new Regex(disciplineRegex.Value, RegexOptions.IgnoreCase); } + if (lowDisciplineRegex.Value != null) + { + _lowDisciplineRegex = new Regex(lowDisciplineRegex.Value, RegexOptions.IgnoreCase); + } + if (nodeNameRegex.Value != null) { _nodeNameRegex = new Regex(nodeNameRegex.Value, RegexOptions.IgnoreCase); } } - public NodePriority GetPriority(string discipline, string nodeName) + public NodePriority GetPriority(string discipline) { - if (_nodeNameRegex != null && _nodeNameRegex.IsMatch(nodeName)) - return NodePriority.High; + // TODO + // if (_nodeNameRegex != null && _nodeNameRegex.IsMatch(nodeName)) + // return NodePriority.High; if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) return NodePriority.Medium; + if (_lowDisciplineRegex != null && _lowDisciplineRegex.IsMatch(discipline)) + return NodePriority.Low; + return NodePriority.Default; } } diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 7f5d8c332..767a976c2 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -5,6 +5,8 @@ namespace CadRevealComposer.Operations.SectorSplitting; using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; +using System.Drawing; using System.Linq; using Utils; @@ -99,7 +101,6 @@ int depthToStartSplittingGeometry * Note: Voxels might have partial overlap, to place nodes that is between two sectors without duplicating the data. * Important: Geometries are grouped by NodeId and the group as a whole is placed into the same voxel (that encloses all the geometries in the group). */ - if (nodes.Length == 0) { yield break; @@ -320,16 +321,24 @@ private static IEnumerable GetNodesByBudget(IReadOnlyList nodes, lon { var selectedNodes = actualDepth switch { - 1 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_1).ToArray(), + 1 + => nodes + .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_1) + .ToArray(), 2 => nodes - .Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_2 || x.Priority == NodePriority.Medium) + .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_2) + .ToArray(), + 3 + => nodes + .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_3) .ToArray(), - 3 => nodes.Where(x => x.Diagonal >= MinDiagonalSizeAtDepth_3).ToArray(), _ => nodes.ToArray(), }; - var nodesInPrioritizedOrder = selectedNodes.OrderByDescending(x => x.Diagonal); + var nodesInPrioritizedOrder = selectedNodes.OrderByDescending( + x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) + ); var budgetLeft = budget; var nodeArray = nodesInPrioritizedOrder.ToArray(); diff --git a/CadRevealComposer/Operations/SectorSplitting/TooFewInstancesHandler.cs b/CadRevealComposer/Operations/SectorSplitting/TooFewInstancesHandler.cs index 7f34590f6..77a6aa4dc 100644 --- a/CadRevealComposer/Operations/SectorSplitting/TooFewInstancesHandler.cs +++ b/CadRevealComposer/Operations/SectorSplitting/TooFewInstancesHandler.cs @@ -41,7 +41,8 @@ private TriangleMesh ConvertInstanceToMesh(InstancedMesh instanceMesh) newMesh, instanceMesh.TreeIndex, instanceMesh.Color, - instanceMesh.AxisAlignedBoundingBox + instanceMesh.AxisAlignedBoundingBox, + instanceMesh.NodePriority ); } diff --git a/CadRevealComposer/Primitives/APrimitive.cs b/CadRevealComposer/Primitives/APrimitive.cs index 4122aeea9..ca960158e 100644 --- a/CadRevealComposer/Primitives/APrimitive.cs +++ b/CadRevealComposer/Primitives/APrimitive.cs @@ -160,5 +160,5 @@ public abstract record APrimitive( ulong TreeIndex, Color Color, BoundingBox AxisAlignedBoundingBox, - NodePriority NodePriority = NodePriority.Default + NodePriority NodePriority ); diff --git a/CadRevealFbxProvider.Tests/FbxProviderTests.cs b/CadRevealFbxProvider.Tests/FbxProviderTests.cs index d81bc8973..433cf661b 100644 --- a/CadRevealFbxProvider.Tests/FbxProviderTests.cs +++ b/CadRevealFbxProvider.Tests/FbxProviderTests.cs @@ -34,6 +34,7 @@ public class FbxProviderTests false, new NodeNameExcludeRegex(null), new PrioritizedDisciplinesRegex(null), + new LowPrioritizedDisciplineRegex(null), new PrioritizedNodeNamesRegex(null) ); @@ -144,7 +145,11 @@ public void SampleModel_AttributeTest() treeIndexGenerator, instanceIndexGenerator, new NodeNameFiltering(new NodeNameExcludeRegex(null)), - new PriorityMapping(new PrioritizedDisciplinesRegex(null), new PrioritizedNodeNamesRegex(null)) + new PriorityMapping( + new PrioritizedDisciplinesRegex(null), + new LowPrioritizedDisciplineRegex(null), + new PrioritizedNodeNamesRegex(null) + ) ); Assert.That(nodes, Has.Count.EqualTo(28)); diff --git a/CadRevealObjProvider.Tests/ObjProviderTests.cs b/CadRevealObjProvider.Tests/ObjProviderTests.cs index c09467799..35b0657ec 100644 --- a/CadRevealObjProvider.Tests/ObjProviderTests.cs +++ b/CadRevealObjProvider.Tests/ObjProviderTests.cs @@ -21,7 +21,11 @@ public void ObjProviderTests_SmokeTest() treeIndexGenerator, instanceIdGenerator, new NodeNameFiltering(new NodeNameExcludeRegex(null)), - new PriorityMapping(new PrioritizedDisciplinesRegex(null), new PrioritizedNodeNamesRegex(null)) + new PriorityMapping( + new PrioritizedDisciplinesRegex(null), + new LowPrioritizedDisciplineRegex(null), + new PrioritizedNodeNamesRegex(null) + ) ); } } diff --git a/CadRevealRvmProvider.Tests/RvmPyramidInstancerTests.cs b/CadRevealRvmProvider.Tests/RvmPyramidInstancerTests.cs index 8c0f4edd6..46de16211 100644 --- a/CadRevealRvmProvider.Tests/RvmPyramidInstancerTests.cs +++ b/CadRevealRvmProvider.Tests/RvmPyramidInstancerTests.cs @@ -1,6 +1,7 @@ namespace CadRevealRvmProvider.Tests; using CadRevealComposer; +using CadRevealComposer.Operations; using Operations; using RvmSharp.Primitives; using System.Drawing; @@ -23,9 +24,27 @@ public void Process_WhenTwoIdenticalMeshes_IgnoresOneOfThem() // Mark: These two input pyramids will be identical as they are Records with identical values. ProtoMeshFromRvmPyramid[] protoPyramids = new[] { - new ProtoMeshFromRvmPyramid(rvmPyramid, 0, Color.Red, new BoundingBox(Vector3.One, Vector3.One)), - new ProtoMeshFromRvmPyramid(rvmPyramid, 0, Color.Red, new BoundingBox(Vector3.One, Vector3.One)), - new ProtoMeshFromRvmPyramid(rvmPyramidNotMatching, 0, Color.Red, new BoundingBox(Vector3.One, Vector3.One)) + new ProtoMeshFromRvmPyramid( + rvmPyramid, + 0, + Color.Red, + new BoundingBox(Vector3.One, Vector3.One), + NodePriority.Default + ), + new ProtoMeshFromRvmPyramid( + rvmPyramid, + 0, + Color.Red, + new BoundingBox(Vector3.One, Vector3.One), + NodePriority.Default + ), + new ProtoMeshFromRvmPyramid( + rvmPyramidNotMatching, + 0, + Color.Red, + new BoundingBox(Vector3.One, Vector3.One), + NodePriority.Default + ) }; var res = RvmPyramidInstancer.Process(protoPyramids, _ => true); @@ -67,7 +86,13 @@ public void TwoPyramidsWithSimilarProportionsAreTheSame() var protoPyramids = new[] { rvmPyramidA, rvmPyramidAHalfScaled, rvmPyramidCUnique } .Select( rvmPyramid => - new ProtoMeshFromRvmPyramid(rvmPyramid, 0, Color.Red, new BoundingBox(Vector3.One, Vector3.One)) + new ProtoMeshFromRvmPyramid( + rvmPyramid, + 0, + Color.Red, + new BoundingBox(Vector3.One, Vector3.One), + NodePriority.Default + ) ) .ToArray(); diff --git a/CadRevealRvmProvider/Converters/RvmFacetGroupConverter.cs b/CadRevealRvmProvider/Converters/RvmFacetGroupConverter.cs index c6a2560dd..e83abd53a 100644 --- a/CadRevealRvmProvider/Converters/RvmFacetGroupConverter.cs +++ b/CadRevealRvmProvider/Converters/RvmFacetGroupConverter.cs @@ -1,5 +1,6 @@ namespace CadRevealRvmProvider.Converters; +using CadRevealComposer.Operations; using CadRevealComposer.Primitives; using RvmSharp.Primitives; using System.Drawing; @@ -16,7 +17,8 @@ Color color rvmFacetGroup, treeIndex, color, - rvmFacetGroup.CalculateAxisAlignedBoundingBox()!.ToCadRevealBoundingBox() + rvmFacetGroup.CalculateAxisAlignedBoundingBox()!.ToCadRevealBoundingBox(), + NodePriority.Default ); } } diff --git a/CadRevealRvmProvider/Converters/RvmPyramidConverter.cs b/CadRevealRvmProvider/Converters/RvmPyramidConverter.cs index dab7b2d5e..14bec25e1 100644 --- a/CadRevealRvmProvider/Converters/RvmPyramidConverter.cs +++ b/CadRevealRvmProvider/Converters/RvmPyramidConverter.cs @@ -1,5 +1,6 @@ namespace CadRevealRvmProvider.Converters; +using CadRevealComposer.Operations; using CadRevealComposer.Primitives; using CadRevealComposer.Utils; using RvmSharp.Operations; @@ -42,7 +43,8 @@ Color color rvmPyramid, treeIndex, color, - rvmPyramid.CalculateAxisAlignedBoundingBox()!.ToCadRevealBoundingBox() + rvmPyramid.CalculateAxisAlignedBoundingBox()!.ToCadRevealBoundingBox(), + NodePriority.Default ); } } diff --git a/CadRevealRvmProvider/RvmProtoMesh.cs b/CadRevealRvmProvider/RvmProtoMesh.cs index c7bdbddc4..11a0dac31 100644 --- a/CadRevealRvmProvider/RvmProtoMesh.cs +++ b/CadRevealRvmProvider/RvmProtoMesh.cs @@ -1,6 +1,8 @@ namespace CadRevealRvmProvider; using CadRevealComposer; +using CadRevealComposer.Operations; +using CadRevealComposer.Operations.SectorSplitting; using CadRevealComposer.Primitives; using RvmSharp.Primitives; using System.Drawing; @@ -11,22 +13,25 @@ public abstract record ProtoMesh( RvmPrimitive RvmPrimitive, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority Priority +) : APrimitive(TreeIndex, Color, AxisAlignedBoundingBox, Priority); public sealed record ProtoMeshFromFacetGroup( RvmFacetGroup FacetGroup, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : ProtoMesh(FacetGroup, TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority Priority +) : ProtoMesh(FacetGroup, TreeIndex, Color, AxisAlignedBoundingBox, Priority); public sealed record ProtoMeshFromRvmPyramid( RvmPyramid Pyramid, ulong TreeIndex, Color Color, - BoundingBox AxisAlignedBoundingBox -) : ProtoMesh(Pyramid, TreeIndex, Color, AxisAlignedBoundingBox); + BoundingBox AxisAlignedBoundingBox, + NodePriority Priority +) : ProtoMesh(Pyramid, TreeIndex, Color, AxisAlignedBoundingBox, Priority); /// /// Sole purpose is to keep the through processing of facet group instancing. diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index 5ac57eb21..7c3366bb9 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -42,7 +42,18 @@ PriorityMapping priorityMapping Trace.Assert(subBoundingBox != null, "Root node has no bounding box. Are there any meshes in the input?"); + foreach (CadRevealNode cadRevealRootNode in cadRevealRootNodes) + { + var allChildren = CadRevealNode.GetAllNodesFlat(cadRevealRootNode); + var pri = priorityMapping.GetPriority(cadRevealRootNode.Attributes.GetValueOrNull(("Discipline")) ?? "lol"); // TODO + foreach (CadRevealNode node in allChildren) + { + node.Geometries = node.Geometries.Select(g => g with { NodePriority = pri }).ToArray(); + } + } + var allNodes = cadRevealRootNodes.SelectMany(CadRevealNode.GetAllNodesFlat).ToArray(); + return allNodes; } @@ -139,21 +150,6 @@ PriorityMapping priorityMapping ? primitiveAndChildrenBoundingBoxes.Aggregate((a, b) => a.Encapsulate(b)) : null; - if (newNode.Attributes.Count > 0) - { - var discipline = newNode.Attributes["Discipline"]; - var name = newNode.Name; - var priority = priorityMapping.GetPriority(discipline, name); - - var geometriesWithPriority = new List(); - foreach (var geometry in newNode.Geometries) - { - geometriesWithPriority.Add(geometry with { NodePriority = priority }); - } - - newNode.Geometries = geometriesWithPriority.ToArray(); - } - return newNode; } } diff --git a/CadRevealRvmProvider/Tessellation/RvmTessellator.cs b/CadRevealRvmProvider/Tessellation/RvmTessellator.cs index 219cbfd71..12548b8ef 100644 --- a/CadRevealRvmProvider/Tessellation/RvmTessellator.cs +++ b/CadRevealRvmProvider/Tessellation/RvmTessellator.cs @@ -26,7 +26,13 @@ InstanceIdGenerator instanceIdGenerator static TriangleMesh TessellateAndCreateTriangleMesh(ProtoMesh p) { var mesh = Tessellate(p.RvmPrimitive); - return new TriangleMesh(ConvertRvmMesh(mesh), p.TreeIndex, p.Color, p.AxisAlignedBoundingBox); + return new TriangleMesh( + ConvertRvmMesh(mesh), + p.TreeIndex, + p.Color, + p.AxisAlignedBoundingBox, + p.NodePriority + ); } var facetGroupsNotInstanced = facetGroupInstancingResult @@ -85,7 +91,8 @@ static TriangleMesh TessellateAndCreateTriangleMesh(ProtoMesh p) item.Transform, item.ProtoMesh.TreeIndex, item.ProtoMesh.Color, - item.ProtoMesh.AxisAlignedBoundingBox + item.ProtoMesh.AxisAlignedBoundingBox, + item.ProtoMesh.NodePriority ) ) ) From 82512dacf4f71129b9b9cb242a141b10faf1b5f0 Mon Sep 17 00:00:00 2001 From: vegasten Date: Fri, 8 Sep 2023 11:28:33 +0200 Subject: [PATCH 06/15] Try to prioritize type VALV --- .../SectorSplitting/SectorSplitterOctree.cs | 25 ++++++++++--------- .../RvmStoreToCadRevealNodesConverter.cs | 15 +++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 767a976c2..d55861d02 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -321,18 +321,9 @@ private static IEnumerable GetNodesByBudget(IReadOnlyList nodes, lon { var selectedNodes = actualDepth switch { - 1 - => nodes - .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_1) - .ToArray(), - 2 - => nodes - .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_2) - .ToArray(), - 3 - => nodes - .Where(x => x.Diagonal * (x.Priority == NodePriority.Low ? 0.5f : 1) >= MinDiagonalSizeAtDepth_3) - .ToArray(), + 1 => nodes.Where(x => x.Diagonal * GetPriorityWeighting(x) >= MinDiagonalSizeAtDepth_1).ToArray(), + 2 => nodes.Where(x => x.Diagonal * GetPriorityWeighting(x) >= MinDiagonalSizeAtDepth_2).ToArray(), + 3 => nodes.Where(x => x.Diagonal * GetPriorityWeighting(x) >= MinDiagonalSizeAtDepth_3).ToArray(), _ => nodes.ToArray(), }; @@ -356,4 +347,14 @@ private static IEnumerable GetNodesByBudget(IReadOnlyList nodes, lon yield return node; } } + + private static float GetPriorityWeighting(Node node) + { + if (node.Priority == NodePriority.Low) + return 0.5f; + if (node.Priority == NodePriority.Medium) + return 10.0f; + + return 1; + } } diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index 7c3366bb9..c49ba3088 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -54,6 +54,21 @@ PriorityMapping priorityMapping var allNodes = cadRevealRootNodes.SelectMany(CadRevealNode.GetAllNodesFlat).ToArray(); + allNodes = allNodes + .Select(node => + { + var type = node.Attributes.GetValueOrNull("Type") ?? "lol"; + if (type.Equals("VALV")) + { + node.Geometries = node.Geometries + .Select(g => g with { NodePriority = NodePriority.Medium }) + .ToArray(); + } + + return node; + }) + .ToArray(); + return allNodes; } From 4f1dd0933069e48dcf6ea65b06b60a2b876a1756 Mon Sep 17 00:00:00 2001 From: vegasten Date: Fri, 8 Sep 2023 11:42:49 +0200 Subject: [PATCH 07/15] Prioritize the largest geometries of valves --- .../RvmStoreToCadRevealNodesConverter.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index c49ba3088..d41ca65d0 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -9,6 +9,7 @@ namespace CadRevealRvmProvider.Converters; using RvmSharp.Primitives; using System.Diagnostics; using System.Drawing; +using System.Drawing.Text; internal static class RvmStoreToCadRevealNodesConverter { @@ -60,9 +61,20 @@ PriorityMapping priorityMapping var type = node.Attributes.GetValueOrNull("Type") ?? "lol"; if (type.Equals("VALV")) { - node.Geometries = node.Geometries - .Select(g => g with { NodePriority = NodePriority.Medium }) + var geometries = node.Geometries; + var sortedGeometries = geometries + .OrderByDescending(x => x.AxisAlignedBoundingBox.Diagonal) .ToArray(); + + int numberOfGeometriesToPrioritize = 5; // Arbitrary number + if (sortedGeometries.Length < numberOfGeometriesToPrioritize) + numberOfGeometriesToPrioritize = sortedGeometries.Length; + + for (int i = 0; i < numberOfGeometriesToPrioritize; i++) + { + sortedGeometries[i] = sortedGeometries[i] with { NodePriority = NodePriority.Medium }; + } + node.Geometries = sortedGeometries; } return node; From 91b4698c93c5df9f20cc8889ab5ef08f29e6d047 Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 13 Sep 2023 11:24:59 +0200 Subject: [PATCH 08/15] Hardcode low priority for STRU --- CadRevealComposer/Operations/PriorityMapping.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/CadRevealComposer/Operations/PriorityMapping.cs b/CadRevealComposer/Operations/PriorityMapping.cs index a3690f46b..363463e91 100644 --- a/CadRevealComposer/Operations/PriorityMapping.cs +++ b/CadRevealComposer/Operations/PriorityMapping.cs @@ -1,6 +1,7 @@ namespace CadRevealComposer.Operations; using Configuration; +using Microsoft.EntityFrameworkCore.Update; using System.Text.RegularExpressions; public enum NodePriority @@ -45,10 +46,17 @@ public NodePriority GetPriority(string discipline) // if (_nodeNameRegex != null && _nodeNameRegex.IsMatch(nodeName)) // return NodePriority.High; - if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) - return NodePriority.Medium; - if (_lowDisciplineRegex != null && _lowDisciplineRegex.IsMatch(discipline)) + // TODO + //if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) + // return NodePriority.Medium; + + // TODO + //if (_lowDisciplineRegex != null && _lowDisciplineRegex.IsMatch(discipline)) + // return NodePriority.Low; + + // Hardcoded low priority on STRU for testing + if (discipline.Equals("STRU")) return NodePriority.Low; return NodePriority.Default; From d3300e766cdc5db41d5fe87f5194766466f4faf1 Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 13 Sep 2023 13:17:45 +0200 Subject: [PATCH 09/15] Prioritize valves more (20) --- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index d55861d02..57db00291 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -5,8 +5,6 @@ namespace CadRevealComposer.Operations.SectorSplitting; using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; -using System.Drawing; using System.Linq; using Utils; @@ -353,7 +351,7 @@ private static float GetPriorityWeighting(Node node) if (node.Priority == NodePriority.Low) return 0.5f; if (node.Priority == NodePriority.Medium) - return 10.0f; + return 20.0f; return 1; } From fc7d67d3d3db4e837bf3dc161894c829fdee57ca Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 13 Sep 2023 13:47:52 +0200 Subject: [PATCH 10/15] Prioritize valves more (100) --- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 57db00291..e63870441 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -351,7 +351,7 @@ private static float GetPriorityWeighting(Node node) if (node.Priority == NodePriority.Low) return 0.5f; if (node.Priority == NodePriority.Medium) - return 20.0f; + return 100.0f; return 1; } From c666cd75506a101ec702a80533a5421d2c2b8e90 Mon Sep 17 00:00:00 2001 From: vegasten Date: Wed, 13 Sep 2023 14:57:02 +0200 Subject: [PATCH 11/15] Prioritize valves more (10000) --- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index e63870441..1da46aea3 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -351,7 +351,7 @@ private static float GetPriorityWeighting(Node node) if (node.Priority == NodePriority.Low) return 0.5f; if (node.Priority == NodePriority.Medium) - return 100.0f; + return 10000.0f; return 1; } From 5f51eb3c5ed2860c66e91221b03bbf0f056e60fb Mon Sep 17 00:00:00 2001 From: "Vegard Stengrundet (Omega AS)" Date: Thu, 14 Sep 2023 10:00:34 +0200 Subject: [PATCH 12/15] Test with all parts of valve --- CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index d41ca65d0..d791197f1 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -66,7 +66,7 @@ PriorityMapping priorityMapping .OrderByDescending(x => x.AxisAlignedBoundingBox.Diagonal) .ToArray(); - int numberOfGeometriesToPrioritize = 5; // Arbitrary number + int numberOfGeometriesToPrioritize = 1000; // Arbitrary number if (sortedGeometries.Length < numberOfGeometriesToPrioritize) numberOfGeometriesToPrioritize = sortedGeometries.Length; From 0ca1a7df2127181e7f8146e5079b2619c3931c62 Mon Sep 17 00:00:00 2001 From: "Vegard Stengrundet (Omega AS)" Date: Thu, 14 Sep 2023 13:21:04 +0200 Subject: [PATCH 13/15] Set valve weighting to 20 --- .../Operations/SectorSplitting/SectorSplitterOctree.cs | 2 +- CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs index 1da46aea3..d7d59d031 100644 --- a/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs +++ b/CadRevealComposer/Operations/SectorSplitting/SectorSplitterOctree.cs @@ -351,7 +351,7 @@ private static float GetPriorityWeighting(Node node) if (node.Priority == NodePriority.Low) return 0.5f; if (node.Priority == NodePriority.Medium) - return 10000.0f; + return 30.0f; return 1; } diff --git a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs index d791197f1..d41ca65d0 100644 --- a/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs +++ b/CadRevealRvmProvider/RvmStoreToCadRevealNodesConverter.cs @@ -66,7 +66,7 @@ PriorityMapping priorityMapping .OrderByDescending(x => x.AxisAlignedBoundingBox.Diagonal) .ToArray(); - int numberOfGeometriesToPrioritize = 1000; // Arbitrary number + int numberOfGeometriesToPrioritize = 5; // Arbitrary number if (sortedGeometries.Length < numberOfGeometriesToPrioritize) numberOfGeometriesToPrioritize = sortedGeometries.Length; From d147a6faf5a8bdf793da01aa6896106a6bcad224 Mon Sep 17 00:00:00 2001 From: vegasten Date: Thu, 1 Aug 2024 23:22:58 +0200 Subject: [PATCH 14/15] Enable discipline priority with PIPE as default --- CadRevealComposer.Exe/CommandLineOptions.cs | 2 +- CadRevealComposer/Operations/PriorityMapping.cs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CadRevealComposer.Exe/CommandLineOptions.cs b/CadRevealComposer.Exe/CommandLineOptions.cs index a8c7ca3ab..0384e7b0d 100644 --- a/CadRevealComposer.Exe/CommandLineOptions.cs +++ b/CadRevealComposer.Exe/CommandLineOptions.cs @@ -83,7 +83,7 @@ public class CommandLineOptions Required = false, HelpText = "A regex matching disciplines to be prioritized in sector splitting. Not case sensitive." )] - public string? PrioritizedDisciplineRegex { get; init; } = null; + public string? PrioritizedDisciplineRegex { get; init; } = "PIPE"; [Option( longName: "LowPrioritizedDiscipline", diff --git a/CadRevealComposer/Operations/PriorityMapping.cs b/CadRevealComposer/Operations/PriorityMapping.cs index 363463e91..357ef798c 100644 --- a/CadRevealComposer/Operations/PriorityMapping.cs +++ b/CadRevealComposer/Operations/PriorityMapping.cs @@ -46,18 +46,16 @@ public NodePriority GetPriority(string discipline) // if (_nodeNameRegex != null && _nodeNameRegex.IsMatch(nodeName)) // return NodePriority.High; - - // TODO - //if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) - // return NodePriority.Medium; + if (_disciplineRegex != null && _disciplineRegex.IsMatch(discipline)) + return NodePriority.Medium; // TODO //if (_lowDisciplineRegex != null && _lowDisciplineRegex.IsMatch(discipline)) // return NodePriority.Low; // Hardcoded low priority on STRU for testing - if (discipline.Equals("STRU")) - return NodePriority.Low; + //if (discipline.Equals("STRU")) + // return NodePriority.Low; return NodePriority.Default; } From 5baf690f2bfc72032e8ddb889c1cd8e663c235c3 Mon Sep 17 00:00:00 2001 From: vegasten Date: Fri, 2 Aug 2024 10:31:29 +0200 Subject: [PATCH 15/15] Fix test --- .../Splitting/SplittingUtilsTests.cs | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/CadRevealComposer.Tests/Operations/Splitting/SplittingUtilsTests.cs b/CadRevealComposer.Tests/Operations/Splitting/SplittingUtilsTests.cs index 69bf8cd08..8c40ee248 100644 --- a/CadRevealComposer.Tests/Operations/Splitting/SplittingUtilsTests.cs +++ b/CadRevealComposer.Tests/Operations/Splitting/SplittingUtilsTests.cs @@ -1,6 +1,7 @@ namespace CadRevealComposer.Tests.Operations.Splitting; using System.Numerics; +using CadRevealComposer.Operations; using CadRevealComposer.Operations.SectorSplitting; using NUnit.Framework.Legacy; @@ -12,10 +13,17 @@ public void ReturnsCorrectlySplitNodes() { Node[] nodes = new Node[] { - new Node(4, null, 0, 0, new BoundingBox(Vector3.One, Vector3.Zero)), - new Node(2, null, 0, 0, new BoundingBox(Vector3.Zero, Vector3.One)), - new Node(4, null, 0, 0, new BoundingBox(new Vector3(99, 99, 99), new Vector3(100, 100, 100))), - new Node(6, null, 0, 0, new BoundingBox(Vector3.One, Vector3.One)) + new Node(4, null, 0, 0, new BoundingBox(Vector3.One, Vector3.Zero), NodePriority.Default), + new Node(2, null, 0, 0, new BoundingBox(Vector3.Zero, Vector3.One), NodePriority.Default), + new Node( + 4, + null, + 0, + 0, + new BoundingBox(new Vector3(99, 99, 99), new Vector3(100, 100, 100)), + NodePriority.Default + ), + new Node(6, null, 0, 0, new BoundingBox(Vector3.One, Vector3.One), NodePriority.Default) }; (Node[] regularNodes, Node[] outlierNodes) = nodes.SplitNodesIntoRegularAndOutlierNodes(); @@ -30,9 +38,16 @@ public void Splitting_ReturnsOutlierSectors() { Node[] nodes = new Node[] { - new Node(4, null, 0, 0, new BoundingBox(Vector3.One, Vector3.Zero)), - new Node(4, null, 0, 0, new BoundingBox(new Vector3(99, 99, 99), new Vector3(100, 100, 100))), - new Node(6, null, 0, 0, new BoundingBox(Vector3.One, Vector3.One)) + new Node(4, null, 0, 0, new BoundingBox(Vector3.One, Vector3.Zero), NodePriority.Default), + new Node( + 4, + null, + 0, + 0, + new BoundingBox(new Vector3(99, 99, 99), new Vector3(100, 100, 100)), + NodePriority.Default + ), + new Node(6, null, 0, 0, new BoundingBox(Vector3.One, Vector3.One), NodePriority.Default) }; var groups = SplittingUtils.GroupOutliersRecursive(nodes, 10f); @@ -45,9 +60,23 @@ public void Splitting_ReturnsOutlierSectorsWhenSymmetrical() { Node[] nodes = new Node[] { - new Node(4, null, 0, 0, new BoundingBox(Vector3.Zero, Vector3.Zero)), - new Node(4, null, 0, 0, new BoundingBox(new Vector3(90, 90, 90), new Vector3(100, 100, 100))), - new Node(4, null, 0, 0, new BoundingBox(new Vector3(-90, -90, -90), new Vector3(-100, -100, -100))), + new Node(4, null, 0, 0, new BoundingBox(Vector3.Zero, Vector3.Zero), NodePriority.Default), + new Node( + 4, + null, + 0, + 0, + new BoundingBox(new Vector3(90, 90, 90), new Vector3(100, 100, 100)), + NodePriority.Default + ), + new Node( + 4, + null, + 0, + 0, + new BoundingBox(new Vector3(-90, -90, -90), new Vector3(-100, -100, -100)), + NodePriority.Default + ), }; var groups = SplittingUtils.GroupOutliersRecursive(nodes, 10f);