From 6a459edaa7291654d725ce8e50ba11452aa765b3 Mon Sep 17 00:00:00 2001 From: hrntsm Date: Sat, 10 Jun 2023 12:01:15 +0900 Subject: [PATCH 1/5] Add s2b convert logger --- HoaryFox/RH7/Component/Geometry/Stb2Brep.cs | 5 +- HoaryFox/RH7/Component/Utils/ConvertLogger.cs | 93 +++ .../Geometry/CreateMemberBrepListFromStb.cs | 608 +++++++++++------- 3 files changed, 475 insertions(+), 231 deletions(-) create mode 100644 HoaryFox/RH7/Component/Utils/ConvertLogger.cs diff --git a/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs b/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs index 18429709..25799f05 100644 --- a/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs +++ b/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Linq; using Grasshopper.Kernel; @@ -75,8 +76,9 @@ protected override void SolveInstance(IGH_DataAccess dataAccess) private void CreateBrep() { + var path = Path.GetDirectoryName(Grasshopper.Instances.ComponentServer.FindAssemblyByObject(this).Location); StbMembers member = _stBridge.StbModel.StbMembers; - var brepFromStb = new CreateMemberBrepListFromStb(_stBridge.StbModel.StbSections, _stBridge.StbModel.StbNodes, new[] { DocumentTolerance(), DocumentAngleTolerance() }); + var brepFromStb = new CreateMemberBrepListFromStb(_stBridge.StbModel.StbSections, _stBridge.StbModel.StbNodes, new[] { DocumentTolerance(), DocumentAngleTolerance() }, path); _brepList[0] = brepFromStb.Column(member.StbColumns); _brepList[1] = brepFromStb.Girder(member.StbGirders); _brepList[2] = brepFromStb.Post(member.StbPosts); @@ -86,6 +88,7 @@ private void CreateBrep() _brepList[6] = brepFromStb.Wall(member.StbWalls, member.StbOpens); _brepList[7] = brepFromStb.Pile(member.StbPiles); _brepList[8] = brepFromStb.Footing(member.StbFootings); + brepFromStb.SerializeLog(); } private void BakeBrep() diff --git a/HoaryFox/RH7/Component/Utils/ConvertLogger.cs b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs new file mode 100644 index 00000000..ef6c5e49 --- /dev/null +++ b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; +using System.Text; + +namespace HoaryFox.Component.Utils +{ + public class ConvertLogger + { + private readonly StringBuilder _logger = new StringBuilder(); + private readonly string _path; + + public ConvertLogger(string path) + { + _path = path; + _logger.AppendLine(@"--------------------------------------"); + _logger.AppendLine(@" ____ ____ ________"); + _logger.AppendLine(@"|_ || _| |_ __ |"); + _logger.AppendLine(@" | |__| | .--. ,--. _ .--. _ __ | |_ \_| .--. _ __"); + _logger.AppendLine(@" | __ | / .'`\ \ `'_\ : [ `/'`\] [ \ [ ] | _| / .'`\ \ [ \ [ ]"); + _logger.AppendLine(@" _| | | |_ | \__. | // | |, | | \ '/ / _| |_ | \__. | > ' <"); + _logger.AppendLine(@"|____||____| '.__.' \'-;__/ [___] [\_: / |_____| '.__.' [__]`\_]"); + _logger.AppendLine(@" \__.'"); + _logger.AppendLine(@" ST-Bridge to Brep Convert Log"); + _logger.AppendLine(@"--------------------------------------"); + _logger.AppendLine($"::INFO :: 変換開始 | {DateTime.Now}"); + } + + public void Clear() + { + _logger.Clear(); + } + + public void AppendInfoMessage(string message) + { + _logger.AppendLine($"::INFO :: {message}"); + } + + public void AppendInfoConvertStartMessage(string message) + { + _logger.AppendLine("--------------------------------------"); + _logger.AppendLine($"::INFO :: {message}の変換を開始しました。 | {DateTime.Now}"); + } + + public void AppendInfoConvertEndMessage(string message) + { + _logger.AppendLine($"::INFO :: {message}の変換を終了しました。 | {DateTime.Now}"); + _logger.AppendLine("--------------------------------------"); + } + + public void AppendInfoDataNotFoundMessage(string message) + { + _logger.AppendLine($"::INFO :: {message}のデータはありませんでした。 | {DateTime.Now}"); + _logger.AppendLine("--------------------------------------"); + } + + public void AppendInfo(string guid, string message) + { + _logger.AppendLine($"::INFO :: [{guid}] | {message}"); + } + + public void AppendConvertSuccess(string guid) + { + _logger.AppendLine($"::INFO :: [{guid}] | 変換完了"); + } + + public void AppendWarning(string guid, string message) + { + _logger.AppendLine($"::WARNING:: [{guid}] | {message}"); + } + + public void AppendError(string guid, string message) + { + _logger.AppendLine($"::ERROR :: [{guid}] | {message}"); + } + + public void AppendConvertFailed(string guid, Exception e) + { + _logger.AppendLine($"::ERROR :: [{guid}] | 変換失敗 | {e.Message}"); + } + + public void AppendSummary(int successCont, int errorCount) + { + _logger.AppendLine($"::INFO :: [SUMMARY] | {successCont} 件の変換に成功しました。"); + _logger.AppendLine($"::INFO :: [SUMMARY] | {errorCount} 件の変換に失敗しました。"); + } + + public void Serialize() + { + AppendInfoConvertEndMessage("ST-BridgeデータのBrepへ"); + File.WriteAllText(_path + "/S2B_convert.log", _logger.ToString()); + } + } +} diff --git a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs index e1eb376d..d5b9e5b2 100644 --- a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs +++ b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Grasshopper.Kernel.Data; @@ -15,260 +16,353 @@ public class CreateMemberBrepListFromStb private readonly IEnumerable _nodes; private readonly IReadOnlyList _tolerance; private readonly StbSections _sections; + private readonly ConvertLogger _logger; - public CreateMemberBrepListFromStb(StbSections sections, IEnumerable nodes, IReadOnlyList tolerance) + public CreateMemberBrepListFromStb(StbSections sections, IEnumerable nodes, IReadOnlyList tolerance, string logPath) { _nodes = nodes; _tolerance = tolerance; _sections = sections; + _logger = new ConvertLogger(logPath); + + } + + public void SerializeLog() + { + _logger.Serialize(); } public GH_Structure Column(IEnumerable columns) { + _logger.AppendInfoConvertStartMessage("柱"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (columns == null) { + _logger.AppendInfoDataNotFoundMessage("柱"); return brepList; } foreach ((StbColumn column, int i) in columns.Select((column, index) => (column, index))) { - StbColumnKind_structure kind = column.kind_structure; - - StbNode[] endNodes = + try { - _nodes.First(node => node.id == column.id_node_bottom), - _nodes.First(node => node.id == column.id_node_top) - }; - Point3d[] offset = - { - new Point3d(column.offset_bottom_X, column.offset_bottom_Y, column.offset_bottom_Z), - new Point3d(column.offset_top_X, column.offset_top_Y, column.offset_top_Z) - }; - Point3d[] sectionPoints = + StbColumnKind_structure kind = column.kind_structure; + StbNode[] endNodes = + { + _nodes.First(node => node.id == column.id_node_bottom), + _nodes.First(node => node.id == column.id_node_top) + }; + Point3d[] offset = + { + new Point3d(column.offset_bottom_X, column.offset_bottom_Y, column.offset_bottom_Z), + new Point3d(column.offset_top_X, column.offset_top_Y, column.offset_top_Z) + }; + Point3d[] sectionPoints = + { + new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], + new Point3d(), + new Point3d(), + new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] + }; + Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; + sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * column.joint_bottom; + sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * column.joint_top; + + var brepMaker = new BrepMaker.Column(_sections, _tolerance, column.guid); + brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(column.id_section, column.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(column.guid); + } + catch (Exception e) { - new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], - new Point3d(), - new Point3d(), - new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] - }; - Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; - sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * column.joint_bottom; - sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * column.joint_top; - - var brepMaker = new BrepMaker.Column(_sections, _tolerance, column.guid); - brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(column.id_section, column.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(column.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("柱"); return brepList; } public GH_Structure Post(IEnumerable posts) { + _logger.AppendInfoConvertStartMessage("間柱"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (posts == null) { + _logger.AppendInfoDataNotFoundMessage("間柱"); return brepList; } foreach ((StbPost post, int i) in posts.Select((post, index) => (post, index))) { - StbColumnKind_structure kind = post.kind_structure; - - StbNode[] endNodes = - { - _nodes.First(node => node.id == post.id_node_bottom), - _nodes.First(node => node.id == post.id_node_top) - }; - Point3d[] offset = + try { - new Point3d(post.offset_bottom_X, post.offset_bottom_Y, post.offset_bottom_Z), - new Point3d(post.offset_top_X, post.offset_top_Y, post.offset_top_Z) - }; - Point3d[] sectionPoints = + StbColumnKind_structure kind = post.kind_structure; + StbNode[] endNodes = + { + _nodes.First(node => node.id == post.id_node_bottom), + _nodes.First(node => node.id == post.id_node_top) + }; + Point3d[] offset = + { + new Point3d(post.offset_bottom_X, post.offset_bottom_Y, post.offset_bottom_Z), + new Point3d(post.offset_top_X, post.offset_top_Y, post.offset_top_Z) + }; + Point3d[] sectionPoints = + { + new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], + new Point3d(), + new Point3d(), + new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] + }; + Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; + sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * post.joint_bottom; + sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * post.joint_top; + + var brepMaker = new BrepMaker.Column(_sections, _tolerance, post.guid); + brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(post.id_section, post.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(post.guid); + } + catch (Exception e) { - new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], - new Point3d(), - new Point3d(), - new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] - }; - Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; - sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * post.joint_bottom; - sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * post.joint_top; - - var brepMaker = new BrepMaker.Column(_sections, _tolerance, post.guid); - brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(post.id_section, post.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(post.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("間柱"); return brepList; } public GH_Structure Girder(IEnumerable girders) { + _logger.AppendInfoConvertStartMessage("大梁"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (girders == null) { + _logger.AppendInfoDataNotFoundMessage("大梁"); return brepList; } foreach ((StbGirder girder, int i) in girders.Select((girder, index) => (girder, index))) { - StbGirderKind_structure kind = girder.kind_structure; - - StbNode[] endNodes = + try { - _nodes.First(node => node.id == girder.id_node_start), - _nodes.First(node => node.id == girder.id_node_end) - }; - Point3d[] offset = - { - new Point3d(girder.offset_start_X, girder.offset_start_Y, girder.offset_start_Z), - new Point3d(girder.offset_end_X, girder.offset_end_Y, girder.offset_end_Z) - }; - Point3d[] sectionPoints = + StbGirderKind_structure kind = girder.kind_structure; + StbNode[] endNodes = + { + _nodes.First(node => node.id == girder.id_node_start), + _nodes.First(node => node.id == girder.id_node_end) + }; + Point3d[] offset = + { + new Point3d(girder.offset_start_X, girder.offset_start_Y, girder.offset_start_Z), + new Point3d(girder.offset_end_X, girder.offset_end_Y, girder.offset_end_Z) + }; + Point3d[] sectionPoints = + { + new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], + Point3d.Origin, // haunch_s + Point3d.Origin, // joint_s + Point3d.Origin, // joint_e + Point3d.Origin, // haunch_e + new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] + }; + Vector3d memberAxis = sectionPoints[5] - sectionPoints[0]; + sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * girder.haunch_start; + sectionPoints[2] = sectionPoints[0] + memberAxis / memberAxis.Length * girder.joint_start; + sectionPoints[3] = sectionPoints[5] - memberAxis / memberAxis.Length * girder.joint_end; + sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * girder.haunch_end; + + var brepMaker = new BrepMaker.Girder(_sections, _tolerance, girder.guid); + brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(girder.id_section, girder.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(girder.guid); + } + catch (Exception e) { - new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], - Point3d.Origin, // haunch_s - Point3d.Origin, // joint_s - Point3d.Origin, // joint_e - Point3d.Origin, // haunch_e - new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] - }; - Vector3d memberAxis = sectionPoints[5] - sectionPoints[0]; - sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * girder.haunch_start; - sectionPoints[2] = sectionPoints[0] + memberAxis / memberAxis.Length * girder.joint_start; - sectionPoints[3] = sectionPoints[5] - memberAxis / memberAxis.Length * girder.joint_end; - sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * girder.haunch_end; - - var brepMaker = new BrepMaker.Girder(_sections, _tolerance, girder.guid); - brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(girder.id_section, girder.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(girder.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("大梁"); return brepList; } public GH_Structure Beam(IEnumerable beams) { + _logger.AppendInfoConvertStartMessage("小梁"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (beams == null) { + _logger.AppendInfoDataNotFoundMessage("小梁"); return brepList; } foreach ((StbBeam beam, int i) in beams.Select((beam, index) => (beam, index))) { - StbGirderKind_structure kind = beam.kind_structure; - - StbNode[] endNodes = - { - _nodes.First(node => node.id == beam.id_node_start), - _nodes.First(node => node.id == beam.id_node_end) - }; - Point3d[] offset = + try { - new Point3d(beam.offset_start_X, beam.offset_start_Y, beam.offset_start_Z), - new Point3d(beam.offset_end_X, beam.offset_end_Y, beam.offset_end_Z) - }; - Point3d[] sectionPoints = + StbGirderKind_structure kind = beam.kind_structure; + StbNode[] endNodes = + { + _nodes.First(node => node.id == beam.id_node_start), + _nodes.First(node => node.id == beam.id_node_end) + }; + Point3d[] offset = + { + new Point3d(beam.offset_start_X, beam.offset_start_Y, beam.offset_start_Z), + new Point3d(beam.offset_end_X, beam.offset_end_Y, beam.offset_end_Z) + }; + Point3d[] sectionPoints = + { + new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], + Point3d.Origin, // haunch_s + Point3d.Origin, // joint_s + Point3d.Origin, // joint_e + Point3d.Origin, // haunch_e + new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] + }; + Vector3d memberAxis = sectionPoints[5] - sectionPoints[0]; + sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * beam.haunch_start; + sectionPoints[2] = sectionPoints[0] + memberAxis / memberAxis.Length * beam.joint_start; + sectionPoints[3] = sectionPoints[5] - memberAxis / memberAxis.Length * beam.joint_end; + sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * beam.haunch_end; + + var brepMaker = new BrepMaker.Girder(_sections, _tolerance, beam.guid); + brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(beam.id_section, beam.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(beam.guid); + } + catch (Exception e) { - new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], - Point3d.Origin, // haunch_s - Point3d.Origin, // joint_s - Point3d.Origin, // joint_e - Point3d.Origin, // haunch_e - new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] - }; - Vector3d memberAxis = sectionPoints[5] - sectionPoints[0]; - sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * beam.haunch_start; - sectionPoints[2] = sectionPoints[0] + memberAxis / memberAxis.Length * beam.joint_start; - sectionPoints[3] = sectionPoints[5] - memberAxis / memberAxis.Length * beam.joint_end; - sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * beam.haunch_end; - - var brepMaker = new BrepMaker.Girder(_sections, _tolerance, beam.guid); - brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(beam.id_section, beam.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(beam.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("小梁"); return brepList; } public GH_Structure Brace(IEnumerable braces) { + _logger.AppendInfoConvertStartMessage("ブレース"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (braces == null) { + _logger.AppendInfoDataNotFoundMessage("ブレース"); return brepList; } foreach ((StbBrace brace, int i) in braces.Select((brace, index) => (brace, index))) { - StbBraceKind_structure kind = brace.kind_structure; - - StbNode[] endNodes = - { - _nodes.First(node => node.id == brace.id_node_start), - _nodes.First(node => node.id == brace.id_node_end) - }; - Point3d[] offset = + try { - new Point3d(brace.offset_start_X, brace.offset_start_Y, brace.offset_start_Z), - new Point3d(brace.offset_end_X, brace.offset_end_Y, brace.offset_end_Z) - }; - Point3d[] sectionPoints = + StbBraceKind_structure kind = brace.kind_structure; + StbNode[] endNodes = + { + _nodes.First(node => node.id == brace.id_node_start), + _nodes.First(node => node.id == brace.id_node_end) + }; + Point3d[] offset = + { + new Point3d(brace.offset_start_X, brace.offset_start_Y, brace.offset_start_Z), + new Point3d(brace.offset_end_X, brace.offset_end_Y, brace.offset_end_Z) + }; + Point3d[] sectionPoints = + { + new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], + Point3d.Origin, + Point3d.Origin, + new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] + }; + Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; + sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * brace.joint_start; + sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * brace.joint_end; + + var brepMaker = new BrepMaker.Brace(_sections, _tolerance, brace.guid); + brepList.Append(new GH_Brep(brepMaker.CreateBraceBrep(brace.id_section, brace.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(brace.guid); + } + catch (Exception e) { - new Point3d(endNodes[0].X, endNodes[0].Y, endNodes[0].Z) + offset[0], - Point3d.Origin, - Point3d.Origin, - new Point3d(endNodes[1].X, endNodes[1].Y, endNodes[1].Z) + offset[1] - }; - Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; - sectionPoints[1] = sectionPoints[0] + memberAxis / memberAxis.Length * brace.joint_start; - sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * brace.joint_end; - - var brepMaker = new BrepMaker.Brace(_sections, _tolerance, brace.guid); - brepList.Append(new GH_Brep(brepMaker.CreateBraceBrep(brace.id_section, brace.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(brace.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("ブレース"); return brepList; } public GH_Structure Slab(IEnumerable slabs) { + _logger.AppendInfoConvertStartMessage("スラブ"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (slabs == null) { + _logger.AppendInfoDataNotFoundMessage("スラブ"); return brepList; } foreach ((StbSlab slab, int i) in slabs.Select((slab, index) => (slab, index))) { - StbSlabOffset[] offsets = slab.StbSlabOffsetList; - var curveList = new PolylineCurve[2]; - double depth = BrepMaker.Slab.GetDepth(_sections, slab); - string[] nodeIds = slab.StbNodeIdOrder.Split(' '); - var topPts = new List(); - foreach (string nodeId in nodeIds) + try { - var offsetVec = new Vector3d(); - if (offsets != null) + StbSlabOffset[] offsets = slab.StbSlabOffsetList; + var curveList = new PolylineCurve[2]; + double depth = BrepMaker.Slab.GetDepth(_sections, slab); + string[] nodeIds = slab.StbNodeIdOrder.Split(' '); + var topPts = new List(); + foreach (string nodeId in nodeIds) { - foreach (StbSlabOffset offset in offsets) + var offsetVec = new Vector3d(); + if (offsets != null) { - if (nodeId == offset.id_node) + foreach (StbSlabOffset offset in offsets) { - offsetVec = new Vector3d(offset.offset_X, offset.offset_Y, offset.offset_Z); + if (nodeId == offset.id_node) + { + offsetVec = new Vector3d(offset.offset_X, offset.offset_Y, offset.offset_Z); + } } } + + StbNode node = _nodes.First(n => n.id == nodeId); + topPts.Add(new Point3d(node.X, node.Y, node.Z) + offsetVec); } - StbNode node = _nodes.First(n => n.id == nodeId); - topPts.Add(new Point3d(node.X, node.Y, node.Z) + offsetVec); + topPts.Add(topPts[0]); + curveList[0] = new PolylineCurve(topPts); + brepList.Append(CreateSlabBrep(depth, curveList, topPts), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(slab.guid); + } + catch (Exception e) + { + convertCount[1]++; + ConvertFailed(slab.guid, e); } - - topPts.Add(topPts[0]); - curveList[0] = new PolylineCurve(topPts); - brepList.Append(CreateSlabBrep(depth, curveList, topPts), new GH_Path(0, i)); } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("スラブ"); return brepList; } @@ -320,49 +414,63 @@ private GH_Brep NonPlanarBrep(double depth, IList curveList) public GH_Structure Wall(IEnumerable walls, IEnumerable opens) { + _logger.AppendInfoConvertStartMessage("壁"); + var convertCount = new int[] { 0, 0 }; var brepList = new GH_Structure(); if (walls == null) { + _logger.AppendInfoDataNotFoundMessage("壁"); return brepList; } foreach ((StbWall wall, int i) in walls.Select((wall, index) => (wall, index))) { - StbWallOffset[] offsets = wall.StbWallOffsetList; - var curveList = new PolylineCurve[2]; - double thickness = BrepMaker.Wall.GetThickness(_sections, wall); - string[] nodeIds = wall.StbNodeIdOrder.Split(' '); - var wallPts = new List(); - foreach (string nodeId in nodeIds) + try { - var offsetVec = new Vector3d(); - if (offsets != null) + StbWallOffset[] offsets = wall.StbWallOffsetList; + var curveList = new PolylineCurve[2]; + double thickness = BrepMaker.Wall.GetThickness(_sections, wall); + string[] nodeIds = wall.StbNodeIdOrder.Split(' '); + var wallPts = new List(); + foreach (string nodeId in nodeIds) { - foreach (StbWallOffset offset in offsets) + var offsetVec = new Vector3d(); + if (offsets != null) { - if (nodeId == offset.id_node) + foreach (StbWallOffset offset in offsets) { - offsetVec = new Vector3d(offset.offset_X, offset.offset_Y, offset.offset_Z); - break; + if (nodeId == offset.id_node) + { + offsetVec = new Vector3d(offset.offset_X, offset.offset_Y, offset.offset_Z); + break; + } } } - } - StbNode node = _nodes.First(n => n.id == nodeId); - wallPts.Add(new Point3d(node.X, node.Y, node.Z) + offsetVec); + StbNode node = _nodes.First(n => n.id == nodeId); + wallPts.Add(new Point3d(node.X, node.Y, node.Z) + offsetVec); + } + wallPts.Add(wallPts[0]); + var centerCurve = new PolylineCurve(wallPts); + Vector3d normal = Vector3d.CrossProduct(centerCurve.TangentAtEnd, centerCurve.TangentAtStart); + curveList[0] = new PolylineCurve(wallPts.Select(pt => pt + normal * thickness / 2)); + curveList[1] = new PolylineCurve(wallPts.Select(pt => pt - normal * thickness / 2)); + Brep brep = Brep.CreateFromLoft(curveList, Point3d.Unset, Point3d.Unset, LoftType.Straight, false)[0].CapPlanarHoles(_tolerance[0]); + CheckBrepOrientation(brep); + + brep = ApplyWallOpen(opens, wall, wallPts, brep); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(wall.guid); + } + catch (Exception e) + { + ConvertFailed(wall.guid, e); } - wallPts.Add(wallPts[0]); - var centerCurve = new PolylineCurve(wallPts); - Vector3d normal = Vector3d.CrossProduct(centerCurve.TangentAtEnd, centerCurve.TangentAtStart); - curveList[0] = new PolylineCurve(wallPts.Select(pt => pt + normal * thickness / 2)); - curveList[1] = new PolylineCurve(wallPts.Select(pt => pt - normal * thickness / 2)); - Brep brep = Brep.CreateFromLoft(curveList, Point3d.Unset, Point3d.Unset, LoftType.Straight, false)[0].CapPlanarHoles(_tolerance[0]); - CheckBrepOrientation(brep); - - brep = ApplyWallOpen(opens, wall, wallPts, brep); - brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("壁"); return brepList; } @@ -438,102 +546,142 @@ private static Point3d[] GetOpenCurvePts(IReadOnlyList wallPts, StbOpen public GH_Structure Pile(IEnumerable piles) { + _logger.AppendInfoConvertStartMessage("杭"); + var convertCount = new[] { 0, 0 }; var brepList = new GH_Structure(); if (piles == null) { + _logger.AppendInfoDataNotFoundMessage("杭"); return brepList; } foreach ((StbPile pile, int i) in piles.Select((pile, index) => (pile, index))) { - StbPileKind_structure kind = pile.kind_structure; - StbNode node = _nodes.First(n => n.id == pile.id_node); - var sectionPoints = new List(); - - switch (kind) + try { - case StbPileKind_structure.RC: - Point3d[] endNodes = - { - new Point3d(node.X, node.Y, node.Z), - new Point3d(node.X, node.Y, node.Z - pile.length_all) - }; - Point3d[] offset = - { - new Point3d(pile.offset_X, pile.offset_Y, pile.level_top), - new Point3d(pile.offset_X, pile.offset_Y, pile.level_top), - }; - sectionPoints = new List - { - endNodes[0] + offset[0], - new Point3d(), - new Point3d(), - endNodes[1] + offset[1] - }; - sectionPoints[1] = sectionPoints[0] - Vector3d.ZAxis * pile.length_head; - break; - case StbPileKind_structure.PC: - var figures = PCPileFigure.GetFigureList(_sections, pile); - sectionPoints.Add(new Point3d - { - X = node.X + pile.offset_X, - Y = node.Y + pile.offset_Y, - Z = node.Z + pile.level_top - }); - foreach ((PCPileFigure figure, int index) in figures.Select((figure, index) => (figure, index))) - { + StbPileKind_structure kind = pile.kind_structure; + StbNode node = _nodes.First(n => n.id == pile.id_node); + var sectionPoints = new List(); + + switch (kind) + { + case StbPileKind_structure.RC: + Point3d[] endNodes = + { + new Point3d(node.X, node.Y, node.Z), + new Point3d(node.X, node.Y, node.Z - pile.length_all) + }; + Point3d[] offset = + { + new Point3d(pile.offset_X, pile.offset_Y, pile.level_top), + new Point3d(pile.offset_X, pile.offset_Y, pile.level_top), + }; + sectionPoints = new List + { + endNodes[0] + offset[0], + new Point3d(), + new Point3d(), + endNodes[1] + offset[1] + }; + sectionPoints[1] = sectionPoints[0] - Vector3d.ZAxis * pile.length_head; + break; + case StbPileKind_structure.PC: + var figures = PCPileFigure.GetFigureList(_sections, pile); sectionPoints.Add(new Point3d { - X = sectionPoints[index].X, - Y = sectionPoints[index].Y, - Z = sectionPoints[index].Z - figure.Length + X = node.X + pile.offset_X, + Y = node.Y + pile.offset_Y, + Z = node.Z + pile.level_top }); - } - break; - } + foreach ((PCPileFigure figure, int index) in figures.Select((figure, index) => (figure, index))) + { + sectionPoints.Add(new Point3d + { + X = sectionPoints[index].X, + Y = sectionPoints[index].Y, + Z = sectionPoints[index].Z - figure.Length + }); + } + break; + } - var brepMaker = new BrepMaker.Pile(_sections, _tolerance, pile.guid); - brepList.Append(new GH_Brep(brepMaker.CreatePileBrep(pile.id_section, kind, sectionPoints, -Vector3d.ZAxis)), new GH_Path(0, i)); + var brepMaker = new BrepMaker.Pile(_sections, _tolerance, pile.guid); + brepList.Append(new GH_Brep(brepMaker.CreatePileBrep(pile.id_section, kind, sectionPoints, -Vector3d.ZAxis)), new GH_Path(0, i)); + convertCount[0]++; + _logger.AppendConvertSuccess(pile.guid); + } + catch (Exception e) + { + convertCount[1]++; + ConvertFailed(pile.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("杭"); return brepList; } public GH_Structure Footing(IEnumerable footings) { + _logger.AppendInfoConvertStartMessage("フーチング"); + var convertCount = new[] { 0, 0 }; var brepList = new GH_Structure(); if (footings == null) { + _logger.AppendInfoDataNotFoundMessage("フーチング"); return brepList; } foreach ((StbFooting footing, int i) in footings.Select((f, index) => (f, index))) { - StbNode node = _nodes.First(n => n.id == footing.id_node); - Point3d[] endNodes = - { - new Point3d(node.X, node.Y, node.Z), - new Point3d(node.X, node.Y, node.Z + footing.level_bottom) - }; - Point3d[] offset = + try { - new Point3d(footing.offset_X, footing.offset_Y, 0), - new Point3d(footing.offset_X, footing.offset_Y, 0), - }; - Point3d[] sectionPoints = + StbNode node = _nodes.First(n => n.id == footing.id_node); + Point3d[] endNodes = + { + new Point3d(node.X, node.Y, node.Z), + new Point3d(node.X, node.Y, node.Z + footing.level_bottom) + }; + Point3d[] offset = + { + new Point3d(footing.offset_X, footing.offset_Y, 0), + new Point3d(footing.offset_X, footing.offset_Y, 0), + }; + Point3d[] sectionPoints = + { + endNodes[0] + offset[0], + new Point3d(), + new Point3d(), + endNodes[1] + offset[1] + }; + Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; + + var brepMaker = new BrepMaker.Footing(_sections, _tolerance, footing.guid); + brepList.Append(new GH_Brep(brepMaker.CreateFootingBrep(footing.id_section, footing.rotate, sectionPoints, memberAxis / memberAxis.Length)), new GH_Path(0, i)); + + convertCount[0]++; + _logger.AppendConvertSuccess(footing.guid); + } + catch (Exception e) { - endNodes[0] + offset[0], - new Point3d(), - new Point3d(), - endNodes[1] + offset[1] - }; - Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; - - var brepMaker = new BrepMaker.Footing(_sections, _tolerance, footing.guid); - brepList.Append(new GH_Brep(brepMaker.CreateFootingBrep(footing.id_section, footing.rotate, sectionPoints, memberAxis / memberAxis.Length)), new GH_Path(0, i)); + convertCount[1]++; + ConvertFailed(footing.guid, e); + } } + _logger.AppendSummary(convertCount[0], convertCount[1]); + _logger.AppendInfoConvertEndMessage("フーチング"); return brepList; } + + private void ConvertFailed(string guid, Exception e) + { + _logger.AppendConvertFailed(guid, e); +#if DEBUG + throw e; +#endif + } + } } From 9d66b00d1b2cf1d22c56a1e5534eac7971c43921 Mon Sep 17 00:00:00 2001 From: hrntsm Date: Sun, 11 Jun 2023 17:38:28 +0900 Subject: [PATCH 2/5] Update convert log --- HoaryFox/RH7/Component/Utils/ConvertLogger.cs | 21 +- .../Geometry/CreateMemberBrepListFromStb.cs | 239 ++++++++++-------- 2 files changed, 152 insertions(+), 108 deletions(-) diff --git a/HoaryFox/RH7/Component/Utils/ConvertLogger.cs b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs index ef6c5e49..bd6c855d 100644 --- a/HoaryFox/RH7/Component/Utils/ConvertLogger.cs +++ b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs @@ -9,7 +9,7 @@ public class ConvertLogger private readonly StringBuilder _logger = new StringBuilder(); private readonly string _path; - public ConvertLogger(string path) + public ConvertLogger(string path, string version) { _path = path; _logger.AppendLine(@"--------------------------------------"); @@ -20,7 +20,8 @@ public ConvertLogger(string path) _logger.AppendLine(@" _| | | |_ | \__. | // | |, | | \ '/ / _| |_ | \__. | > ' <"); _logger.AppendLine(@"|____||____| '.__.' \'-;__/ [___] [\_: / |_____| '.__.' [__]`\_]"); _logger.AppendLine(@" \__.'"); - _logger.AppendLine(@" ST-Bridge to Brep Convert Log"); + _logger.AppendLine($" version:{version}"); + _logger.AppendLine(@" ST-Bridge to Brep Convert Log"); _logger.AppendLine(@"--------------------------------------"); _logger.AppendLine($"::INFO :: 変換開始 | {DateTime.Now}"); } @@ -68,20 +69,26 @@ public void AppendWarning(string guid, string message) _logger.AppendLine($"::WARNING:: [{guid}] | {message}"); } + public void AppendConvertWarning(string guid, string message) + { + _logger.AppendLine($"::WARNING:: [{guid}] | 変換結果 要確認 | {message}"); + } + public void AppendError(string guid, string message) { _logger.AppendLine($"::ERROR :: [{guid}] | {message}"); } - public void AppendConvertFailed(string guid, Exception e) + public void AppendConvertFailed(string guid, string message) { - _logger.AppendLine($"::ERROR :: [{guid}] | 変換失敗 | {e.Message}"); + _logger.AppendLine($"::ERROR :: [{guid}] | 変換失敗 | {message}"); } - public void AppendSummary(int successCont, int errorCount) + public void AppendSummary(int[] resultCount) { - _logger.AppendLine($"::INFO :: [SUMMARY] | {successCont} 件の変換に成功しました。"); - _logger.AppendLine($"::INFO :: [SUMMARY] | {errorCount} 件の変換に失敗しました。"); + _logger.AppendLine($"::INFO :: [SUMMARY] | {resultCount[0]} 件の変換に成功しました。"); + _logger.AppendLine($"::INFO :: [SUMMARY] | {resultCount[1]} 件が変換出来ましたが、結果の確認が必要です。"); + _logger.AppendLine($"::INFO :: [SUMMARY] | {resultCount[2]} 件の変換に失敗しました。"); } public void Serialize() diff --git a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs index d5b9e5b2..b6fc9824 100644 --- a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs +++ b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs @@ -1,4 +1,5 @@ -using System; +using System.Reflection; +using System; using System.Collections.Generic; using System.Linq; @@ -23,8 +24,8 @@ public CreateMemberBrepListFromStb(StbSections sections, IEnumerable no _nodes = nodes; _tolerance = tolerance; _sections = sections; - _logger = new ConvertLogger(logPath); - + var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3); + _logger = new ConvertLogger(logPath, version); } public void SerializeLog() @@ -34,12 +35,13 @@ public void SerializeLog() public GH_Structure Column(IEnumerable columns) { - _logger.AppendInfoConvertStartMessage("柱"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "柱"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (columns == null) { - _logger.AppendInfoDataNotFoundMessage("柱"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -70,30 +72,31 @@ public GH_Structure Column(IEnumerable columns) sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * column.joint_top; var brepMaker = new BrepMaker.Column(_sections, _tolerance, column.guid); - brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(column.id_section, column.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(column.guid); + var brep = brepMaker.CreateColumnBrep(column.id_section, column.rotate, kind, sectionPoints, memberAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, column.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(column.guid, e); + ConvertFailed(resultCount, column.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("柱"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Post(IEnumerable posts) { - _logger.AppendInfoConvertStartMessage("間柱"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "間柱"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0 , 0}; var brepList = new GH_Structure(); if (posts == null) { - _logger.AppendInfoDataNotFoundMessage("間柱"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -124,30 +127,31 @@ public GH_Structure Post(IEnumerable posts) sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * post.joint_top; var brepMaker = new BrepMaker.Column(_sections, _tolerance, post.guid); - brepList.Append(new GH_Brep(brepMaker.CreateColumnBrep(post.id_section, post.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(post.guid); + var brep = brepMaker.CreateColumnBrep(post.id_section, post.rotate, kind, sectionPoints, memberAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, post.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(post.guid, e); + ConvertFailed(resultCount, post.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("間柱"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Girder(IEnumerable girders) { - _logger.AppendInfoConvertStartMessage("大梁"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "大梁"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (girders == null) { - _logger.AppendInfoDataNotFoundMessage("大梁"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -182,30 +186,31 @@ public GH_Structure Girder(IEnumerable girders) sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * girder.haunch_end; var brepMaker = new BrepMaker.Girder(_sections, _tolerance, girder.guid); - brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(girder.id_section, girder.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(girder.guid); + var brep = brepMaker.CreateGirderBrep(girder.id_section, girder.rotate, kind, sectionPoints, memberAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, girder.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(girder.guid, e); + ConvertFailed(resultCount, girder.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("大梁"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Beam(IEnumerable beams) { - _logger.AppendInfoConvertStartMessage("小梁"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "小梁"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0,0 }; var brepList = new GH_Structure(); if (beams == null) { - _logger.AppendInfoDataNotFoundMessage("小梁"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -240,30 +245,31 @@ public GH_Structure Beam(IEnumerable beams) sectionPoints[4] = sectionPoints[5] - memberAxis / memberAxis.Length * beam.haunch_end; var brepMaker = new BrepMaker.Girder(_sections, _tolerance, beam.guid); - brepList.Append(new GH_Brep(brepMaker.CreateGirderBrep(beam.id_section, beam.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(beam.guid); + var brep = brepMaker.CreateGirderBrep(beam.id_section, beam.rotate, kind, sectionPoints, memberAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, beam.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(beam.guid, e); + ConvertFailed(resultCount, beam.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("小梁"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Brace(IEnumerable braces) { - _logger.AppendInfoConvertStartMessage("ブレース"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "ブレース"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (braces == null) { - _logger.AppendInfoDataNotFoundMessage("ブレース"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -294,30 +300,31 @@ public GH_Structure Brace(IEnumerable braces) sectionPoints[2] = sectionPoints[3] - memberAxis / memberAxis.Length * brace.joint_end; var brepMaker = new BrepMaker.Brace(_sections, _tolerance, brace.guid); - brepList.Append(new GH_Brep(brepMaker.CreateBraceBrep(brace.id_section, brace.rotate, kind, sectionPoints, memberAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(brace.guid); + var brep = brepMaker.CreateBraceBrep(brace.id_section, brace.rotate, kind, sectionPoints, memberAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, brace.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(brace.guid, e); + ConvertFailed(resultCount, brace.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("ブレース"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Slab(IEnumerable slabs) { - _logger.AppendInfoConvertStartMessage("スラブ"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "スラブ"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (slabs == null) { - _logger.AppendInfoDataNotFoundMessage("スラブ"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -350,23 +357,23 @@ public GH_Structure Slab(IEnumerable slabs) topPts.Add(topPts[0]); curveList[0] = new PolylineCurve(topPts); - brepList.Append(CreateSlabBrep(depth, curveList, topPts), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(slab.guid); + var brep = CreateSlabBrep(slab.guid, depth, curveList, topPts); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, slab.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(slab.guid, e); + ConvertFailed(resultCount, slab.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("スラブ"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } - private GH_Brep CreateSlabBrep(double depth, IList curveList, IEnumerable topPts) + private Brep CreateSlabBrep(string guid, double depth, IList curveList, IEnumerable topPts) { if (depth > 0) { @@ -377,19 +384,20 @@ private GH_Brep CreateSlabBrep(double depth, IList curveList, IEn if (capedBrep == null) { + _logger.AppendInfo(guid, "スラブがplanerではないため、NetSurfaceで曲面のスラブ生成します。"); return NonPlanarBrep(depth, curveList); } CheckBrepOrientation(capedBrep); - return new GH_Brep(capedBrep); + return capedBrep; } - return new GH_Brep(curveList[0].IsPlanar() + return curveList[0].IsPlanar() ? Brep.CreatePlanarBreps(curveList[0], _tolerance[0])[0] - : Brep.CreatePatch(new[] { curveList[0] }, 5, 5, _tolerance[0])); + : Brep.CreatePatch(new[] { curveList[0] }, 5, 5, _tolerance[0]); } - private GH_Brep NonPlanarBrep(double depth, IList curveList) + private Brep NonPlanarBrep(double depth, IList curveList) { var nonPlanarBrep = new List(); var topBrep = Brep.CreatePatch(new[] { curveList[0] }, 5, 5, _tolerance[0]); @@ -409,17 +417,18 @@ private GH_Brep NonPlanarBrep(double depth, IList curveList) IEnumerable edgeCurveList = topBrep.Edges.Select(edge => edge.DuplicateCurve()); nonPlanarBrep.AddRange(edgeCurveList.Select(edgeCurve => Surface.CreateExtrusion(edgeCurve, faceNormal * depth).ToBrep())); - return new GH_Brep(Brep.JoinBreps(nonPlanarBrep, _tolerance[0])[0] ?? topBrep); + return Brep.JoinBreps(nonPlanarBrep, _tolerance[0])[0] ?? topBrep; } public GH_Structure Wall(IEnumerable walls, IEnumerable opens) { - _logger.AppendInfoConvertStartMessage("壁"); - var convertCount = new int[] { 0, 0 }; + var typeStr = "壁"; + _logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (walls == null) { - _logger.AppendInfoDataNotFoundMessage("壁"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -458,22 +467,23 @@ public GH_Structure Wall(IEnumerable walls, IEnumerable opens, StbWall wall, IReadOnlyList wallPts, Brep brep) + private Brep ApplyWallOpen(string guid, IEnumerable opens, StbWall wall, IReadOnlyList wallPts, Brep brep) { if (brep == null) { @@ -514,6 +524,10 @@ private Brep ApplyWallOpen(IEnumerable opens, StbWall wall, IReadOnlyLi { brep = Brep.CreateBooleanDifference(brep, openBrep, 1)[0]; } + else + { + _logger.AppendWarning(guid, $"開口id:{id}の作成に失敗しました。"); + } } } @@ -546,12 +560,13 @@ private static Point3d[] GetOpenCurvePts(IReadOnlyList wallPts, StbOpen public GH_Structure Pile(IEnumerable piles) { - _logger.AppendInfoConvertStartMessage("杭"); - var convertCount = new[] { 0, 0 }; + var typeString = "杭"; + _logger.AppendInfoConvertStartMessage(typeString); + var resultCount = new[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (piles == null) { - _logger.AppendInfoDataNotFoundMessage("杭"); + _logger.AppendInfoDataNotFoundMessage(typeString); return brepList; } @@ -606,30 +621,31 @@ public GH_Structure Pile(IEnumerable piles) } var brepMaker = new BrepMaker.Pile(_sections, _tolerance, pile.guid); - brepList.Append(new GH_Brep(brepMaker.CreatePileBrep(pile.id_section, kind, sectionPoints, -Vector3d.ZAxis)), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(pile.guid); + var brep = brepMaker.CreatePileBrep(pile.id_section, kind, sectionPoints, -Vector3d.ZAxis); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); + + ConvertResultCheck(resultCount, pile.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(pile.guid, e); + ConvertFailed(resultCount, pile.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("杭"); + _logger.AppendSummary(resultCount); + _logger.AppendInfoConvertEndMessage(typeString); return brepList; } public GH_Structure Footing(IEnumerable footings) { - _logger.AppendInfoConvertStartMessage("フーチング"); - var convertCount = new[] { 0, 0 }; + var typeStr = "フーチング"; + _logger.AppendInfoConvertStartMessage(typeStr); + var convertCount = new[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (footings == null) { - _logger.AppendInfoDataNotFoundMessage("フーチング"); + _logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -658,26 +674,47 @@ public GH_Structure Footing(IEnumerable footings) Vector3d memberAxis = sectionPoints[3] - sectionPoints[0]; var brepMaker = new BrepMaker.Footing(_sections, _tolerance, footing.guid); - brepList.Append(new GH_Brep(brepMaker.CreateFootingBrep(footing.id_section, footing.rotate, sectionPoints, memberAxis / memberAxis.Length)), new GH_Path(0, i)); + var brep = brepMaker.CreateFootingBrep(footing.id_section, footing.rotate, sectionPoints, memberAxis / memberAxis.Length); + brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - convertCount[0]++; - _logger.AppendConvertSuccess(footing.guid); + ConvertResultCheck(convertCount, footing.guid, brep); } catch (Exception e) { - convertCount[1]++; - ConvertFailed(footing.guid, e); + ConvertFailed(convertCount, footing.guid, e); } } - _logger.AppendSummary(convertCount[0], convertCount[1]); - _logger.AppendInfoConvertEndMessage("フーチング"); + _logger.AppendSummary(convertCount); + _logger.AppendInfoConvertEndMessage(typeStr); return brepList; } - private void ConvertFailed(string guid, Exception e) + private void ConvertResultCheck(int[] resultCount, string guid, Brep brep) + { + if (brep == null) + { + resultCount[2]++; + _logger.AppendConvertFailed(guid, "Brepへの変換結果がnullです。"); + return; + } + else if (!brep.IsValid) + { + resultCount[1]++; + _logger.AppendConvertWarning(guid, "BrepがInvalidです。Bakeに失敗する可能性があります。"); + return; + } + else + { + resultCount[0]++; + _logger.AppendConvertSuccess(guid); + } + } + + private void ConvertFailed(int[] resultCount, string guid, Exception e) { - _logger.AppendConvertFailed(guid, e); + resultCount[2]++; + _logger.AppendConvertFailed(guid, e.Message); #if DEBUG throw e; #endif From 480d7a7e51a9fc33aef42dbfa62b2d911da917fa Mon Sep 17 00:00:00 2001 From: hrntsm Date: Sun, 11 Jun 2023 19:22:02 +0900 Subject: [PATCH 3/5] Add log output to s2b component --- HoaryFox/RH7/Component/Geometry/Stb2Brep.cs | 11 +- HoaryFox/RH7/Component/Utils/ConvertLogger.cs | 17 ++- .../Geometry/CreateMemberBrepListFromStb.cs | 139 +++++++++--------- 3 files changed, 87 insertions(+), 80 deletions(-) diff --git a/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs b/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs index 25799f05..06fe8af9 100644 --- a/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs +++ b/HoaryFox/RH7/Component/Geometry/Stb2Brep.cs @@ -42,6 +42,7 @@ protected override void RegisterInputParams(GH_InputParamManager pManager) protected override void RegisterOutputParams(GH_OutputParamManager pManager) { + pManager.AddTextParameter("Log", "Log", "Log", GH_ParamAccess.item); pManager.AddBrepParameter("Columns", "Col", "output StbColumns to Brep", GH_ParamAccess.tree); pManager.AddBrepParameter("Girders", "Gird", "output StbGirders to Brep", GH_ParamAccess.tree); pManager.AddBrepParameter("Posts", "Pst", "output StbPosts to Brep", GH_ParamAccess.tree); @@ -59,22 +60,23 @@ protected override void SolveInstance(IGH_DataAccess dataAccess) if (!dataAccess.GetData("Data", ref _stBridge)) { return; } if (!dataAccess.GetData("Bake", ref isBake)) { return; } - CreateBrep(); + var log = CreateBrep(); if (isBake) { BakeBrep(); } - for (var i = 0; i < 9; i++) + dataAccess.SetData(0, log); + for (var i = 1; i < 10; i++) { - dataAccess.SetDataTree(i, _brepList[i]); + dataAccess.SetDataTree(i, _brepList[i - 1]); } } protected override Bitmap Icon => Resource.Brep; public override Guid ComponentGuid => new Guid("B2D5EA7F-E75F-406B-8D22-C267B43C5E72"); - private void CreateBrep() + private string CreateBrep() { var path = Path.GetDirectoryName(Grasshopper.Instances.ComponentServer.FindAssemblyByObject(this).Location); StbMembers member = _stBridge.StbModel.StbMembers; @@ -89,6 +91,7 @@ private void CreateBrep() _brepList[7] = brepFromStb.Pile(member.StbPiles); _brepList[8] = brepFromStb.Footing(member.StbFootings); brepFromStb.SerializeLog(); + return brepFromStb.Logger.ToString(); } private void BakeBrep() diff --git a/HoaryFox/RH7/Component/Utils/ConvertLogger.cs b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs index bd6c855d..31c034e0 100644 --- a/HoaryFox/RH7/Component/Utils/ConvertLogger.cs +++ b/HoaryFox/RH7/Component/Utils/ConvertLogger.cs @@ -59,9 +59,9 @@ public void AppendInfo(string guid, string message) _logger.AppendLine($"::INFO :: [{guid}] | {message}"); } - public void AppendConvertSuccess(string guid) + public void AppendConvertSuccess(string guid, string tag) { - _logger.AppendLine($"::INFO :: [{guid}] | 変換完了"); + _logger.AppendLine($"::INFO :: [{guid}] | {tag} | 変換完了"); } public void AppendWarning(string guid, string message) @@ -69,9 +69,9 @@ public void AppendWarning(string guid, string message) _logger.AppendLine($"::WARNING:: [{guid}] | {message}"); } - public void AppendConvertWarning(string guid, string message) + public void AppendConvertWarning(string guid, string tag, string message) { - _logger.AppendLine($"::WARNING:: [{guid}] | 変換結果 要確認 | {message}"); + _logger.AppendLine($"::WARNING:: [{guid}] | {tag} | 変換結果 要確認 | {message}"); } public void AppendError(string guid, string message) @@ -79,9 +79,9 @@ public void AppendError(string guid, string message) _logger.AppendLine($"::ERROR :: [{guid}] | {message}"); } - public void AppendConvertFailed(string guid, string message) + public void AppendConvertFailed(string guid, string tag, string message) { - _logger.AppendLine($"::ERROR :: [{guid}] | 変換失敗 | {message}"); + _logger.AppendLine($"::ERROR :: [{guid}] | {tag} | 変換失敗 | {message}"); } public void AppendSummary(int[] resultCount) @@ -96,5 +96,10 @@ public void Serialize() AppendInfoConvertEndMessage("ST-BridgeデータのBrepへ"); File.WriteAllText(_path + "/S2B_convert.log", _logger.ToString()); } + + public override string ToString() + { + return _logger.ToString(); + } } } diff --git a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs index b6fc9824..ecf7e06a 100644 --- a/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs +++ b/HoaryFox/RH7/Component/Utils/Geometry/CreateMemberBrepListFromStb.cs @@ -1,7 +1,7 @@ -using System.Reflection; -using System; +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Grasshopper.Kernel.Data; using Grasshopper.Kernel.Types; @@ -17,7 +17,7 @@ public class CreateMemberBrepListFromStb private readonly IEnumerable _nodes; private readonly IReadOnlyList _tolerance; private readonly StbSections _sections; - private readonly ConvertLogger _logger; + public ConvertLogger Logger { get; private set; } public CreateMemberBrepListFromStb(StbSections sections, IEnumerable nodes, IReadOnlyList tolerance, string logPath) { @@ -25,23 +25,23 @@ public CreateMemberBrepListFromStb(StbSections sections, IEnumerable no _tolerance = tolerance; _sections = sections; var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3); - _logger = new ConvertLogger(logPath, version); + Logger = new ConvertLogger(logPath, version); } public void SerializeLog() { - _logger.Serialize(); + Logger.Serialize(); } public GH_Structure Column(IEnumerable columns) { var typeStr = "柱"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (columns == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -75,28 +75,28 @@ public GH_Structure Column(IEnumerable columns) var brep = brepMaker.CreateColumnBrep(column.id_section, column.rotate, kind, sectionPoints, memberAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, column.guid, brep); + ConvertResultCheck(resultCount, column.guid, column.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, column.guid, e); + ConvertFailed(resultCount, column.guid, column.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Post(IEnumerable posts) { var typeStr = "間柱"; - _logger.AppendInfoConvertStartMessage(typeStr); - var resultCount = new int[] { 0, 0 , 0}; + Logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (posts == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -130,28 +130,28 @@ public GH_Structure Post(IEnumerable posts) var brep = brepMaker.CreateColumnBrep(post.id_section, post.rotate, kind, sectionPoints, memberAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, post.guid, brep); + ConvertResultCheck(resultCount, post.guid, post.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, post.guid, e); + ConvertFailed(resultCount, post.guid, post.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Girder(IEnumerable girders) { var typeStr = "大梁"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (girders == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -189,28 +189,28 @@ public GH_Structure Girder(IEnumerable girders) var brep = brepMaker.CreateGirderBrep(girder.id_section, girder.rotate, kind, sectionPoints, memberAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, girder.guid, brep); + ConvertResultCheck(resultCount, girder.guid, girder.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, girder.guid, e); + ConvertFailed(resultCount, girder.guid, girder.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Beam(IEnumerable beams) { var typeStr = "小梁"; - _logger.AppendInfoConvertStartMessage(typeStr); - var resultCount = new int[] { 0, 0,0 }; + Logger.AppendInfoConvertStartMessage(typeStr); + var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (beams == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -248,28 +248,28 @@ public GH_Structure Beam(IEnumerable beams) var brep = brepMaker.CreateGirderBrep(beam.id_section, beam.rotate, kind, sectionPoints, memberAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, beam.guid, brep); + ConvertResultCheck(resultCount, beam.guid, beam.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, beam.guid, e); + ConvertFailed(resultCount, beam.guid, beam.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Brace(IEnumerable braces) { var typeStr = "ブレース"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (braces == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -303,28 +303,28 @@ public GH_Structure Brace(IEnumerable braces) var brep = brepMaker.CreateBraceBrep(brace.id_section, brace.rotate, kind, sectionPoints, memberAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, brace.guid, brep); + ConvertResultCheck(resultCount, brace.guid, brace.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, brace.guid, e); + ConvertFailed(resultCount, brace.guid, brace.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } public GH_Structure Slab(IEnumerable slabs) { var typeStr = "スラブ"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (slabs == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -360,16 +360,16 @@ public GH_Structure Slab(IEnumerable slabs) var brep = CreateSlabBrep(slab.guid, depth, curveList, topPts); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, slab.guid, brep); + ConvertResultCheck(resultCount, slab.guid, slab.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, slab.guid, e); + ConvertFailed(resultCount, slab.guid, slab.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } @@ -384,7 +384,7 @@ private Brep CreateSlabBrep(string guid, double depth, IList curv if (capedBrep == null) { - _logger.AppendInfo(guid, "スラブがplanerではないため、NetSurfaceで曲面のスラブ生成します。"); + Logger.AppendInfo(guid, "スラブがplanerではないため、NetSurfaceで曲面のスラブ生成します。"); return NonPlanarBrep(depth, curveList); } CheckBrepOrientation(capedBrep); @@ -423,12 +423,12 @@ private Brep NonPlanarBrep(double depth, IList curveList) public GH_Structure Wall(IEnumerable walls, IEnumerable opens) { var typeStr = "壁"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var resultCount = new int[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (walls == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -470,16 +470,16 @@ public GH_Structure Wall(IEnumerable walls, IEnumerable opens, StbWall wall } else { - _logger.AppendWarning(guid, $"開口id:{id}の作成に失敗しました。"); + Logger.AppendWarning(guid, $"開口id:{id}の作成に失敗しました。"); } } } @@ -561,12 +561,12 @@ private static Point3d[] GetOpenCurvePts(IReadOnlyList wallPts, StbOpen public GH_Structure Pile(IEnumerable piles) { var typeString = "杭"; - _logger.AppendInfoConvertStartMessage(typeString); + Logger.AppendInfoConvertStartMessage(typeString); var resultCount = new[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (piles == null) { - _logger.AppendInfoDataNotFoundMessage(typeString); + Logger.AppendInfoDataNotFoundMessage(typeString); return brepList; } @@ -624,28 +624,28 @@ public GH_Structure Pile(IEnumerable piles) var brep = brepMaker.CreatePileBrep(pile.id_section, kind, sectionPoints, -Vector3d.ZAxis); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(resultCount, pile.guid, brep); + ConvertResultCheck(resultCount, pile.guid, pile.name, brep); } catch (Exception e) { - ConvertFailed(resultCount, pile.guid, e); + ConvertFailed(resultCount, pile.guid, pile.name, e); } } - _logger.AppendSummary(resultCount); - _logger.AppendInfoConvertEndMessage(typeString); + Logger.AppendSummary(resultCount); + Logger.AppendInfoConvertEndMessage(typeString); return brepList; } public GH_Structure Footing(IEnumerable footings) { var typeStr = "フーチング"; - _logger.AppendInfoConvertStartMessage(typeStr); + Logger.AppendInfoConvertStartMessage(typeStr); var convertCount = new[] { 0, 0, 0 }; var brepList = new GH_Structure(); if (footings == null) { - _logger.AppendInfoDataNotFoundMessage(typeStr); + Logger.AppendInfoDataNotFoundMessage(typeStr); return brepList; } @@ -677,48 +677,47 @@ public GH_Structure Footing(IEnumerable footings) var brep = brepMaker.CreateFootingBrep(footing.id_section, footing.rotate, sectionPoints, memberAxis / memberAxis.Length); brepList.Append(new GH_Brep(brep), new GH_Path(0, i)); - ConvertResultCheck(convertCount, footing.guid, brep); + ConvertResultCheck(convertCount, footing.guid, footing.name, brep); } catch (Exception e) { - ConvertFailed(convertCount, footing.guid, e); + ConvertFailed(convertCount, footing.guid, footing.name, e); } } - _logger.AppendSummary(convertCount); - _logger.AppendInfoConvertEndMessage(typeStr); + Logger.AppendSummary(convertCount); + Logger.AppendInfoConvertEndMessage(typeStr); return brepList; } - private void ConvertResultCheck(int[] resultCount, string guid, Brep brep) + private void ConvertResultCheck(int[] resultCount, string guid, string tag, Brep brep) { if (brep == null) { resultCount[2]++; - _logger.AppendConvertFailed(guid, "Brepへの変換結果がnullです。"); + Logger.AppendConvertFailed(guid, tag, "Brepへの変換結果がnullです。"); return; } else if (!brep.IsValid) { resultCount[1]++; - _logger.AppendConvertWarning(guid, "BrepがInvalidです。Bakeに失敗する可能性があります。"); + Logger.AppendConvertWarning(guid, tag, "BrepがInvalidです。Bakeに失敗する可能性があります。"); return; } else { resultCount[0]++; - _logger.AppendConvertSuccess(guid); + Logger.AppendConvertSuccess(guid, tag); } } - private void ConvertFailed(int[] resultCount, string guid, Exception e) + private void ConvertFailed(int[] resultCount, string guid, string tag, Exception e) { resultCount[2]++; - _logger.AppendConvertFailed(guid, e.Message); + Logger.AppendConvertFailed(guid, tag, e.Message); #if DEBUG throw e; #endif } - } } From 2047b680aac9821030971515f44d2499edc330aa Mon Sep 17 00:00:00 2001 From: hrntsm Date: Sun, 11 Jun 2023 20:17:17 +0900 Subject: [PATCH 4/5] Update website --- website/docs/Changelog.md | 22 +++++++ website/docs/Component/Geometry.md | 85 ++++++++++++++----------- website/images/Component/StbToBrep.png | Bin 14268 -> 17343 bytes website/images/Component/StbToLine.png | Bin 12191 -> 15644 bytes 4 files changed, 71 insertions(+), 36 deletions(-) diff --git a/website/docs/Changelog.md b/website/docs/Changelog.md index 16ec8488..2d687f0f 100644 --- a/website/docs/Changelog.md +++ b/website/docs/Changelog.md @@ -5,6 +5,28 @@ title: Changelog --- +## [v2.4.0 - 2023-06-11](https://github.com/hrntsm/HoaryFox/releases/tag/v2.4.0) + +### 追加 + +- S2Lコンポーネント + - 杭の可視化対応 + - 節点のオフセットの有無を反映するboolの追加 +- S2Bコンポーネント + - S杭を除く杭の可視化 + - 矩形のフーチングの可視化 + - 変換結果のログ出力と保存 + - 鉄骨のT断面、C断面、L断面の背中合わせ、顔合わせに対応 + - CFT断面の出力 + +### 変更 + +- これまで1つでもエラーがあると変換結果が出力されなかったが、変換エラーの情報をログに記載して、それ以外は出力されるようにした。 + +### 修正 + +- ハンチのある梁のハンチ長がこれまではジョイント長で作成されていたため、ハンチ長で作成するようにした。 + ## [v2.3.0 - 2022-10-15](https://github.com/hrntsm/HoaryFox/releases/tag/v2.3.0) ### 追加 diff --git a/website/docs/Component/Geometry.md b/website/docs/Component/Geometry.md index 435856be..10d8d724 100644 --- a/website/docs/Component/Geometry.md +++ b/website/docs/Component/Geometry.md @@ -13,19 +13,25 @@ title: Geometry 部材を Line で表示する -|入力|説明| -|---|:---:| -|Data|Load STB file コンポーネントの Data 出力を入力| -|Bake|各 Line を断面符号ごとにレイヤー分けして Bake する| - -|出力|説明| -|---|:---:| -|Nodes| 節点の Point3d のリストを出力| -|Columns| 柱の Line のツリーを出力| -|Girders| 大梁の Line のツリーを出力| -|Posts| 間柱の Line のツリーを出力| -|Beams| 小梁の Line のツリーを出力| -|Braces| ブレースの Line のツリーを出力| +| 入力 | 説明 | +| ---------- | :------------------------------------------------: | +| Data | Load STB file コンポーネントの Data 出力を入力 | +| OffsetNode | 部材端部のオフセットの考慮の有無 | +| Bake | 各 Line を断面符号ごとにレイヤー分けして Bake する | + +| 出力 | 説明 | +| ------- | :----------------------------: | +| Nodes | 節点の Point3d のリストを出力 | +| Columns | 柱の Line のツリーを出力 | +| Girders | 大梁の Line のツリーを出力 | +| Posts | 間柱の Line のツリーを出力 | +| Beams | 小梁の Line のツリーを出力 | +| Braces | ブレースの Line のツリーを出力 | +| Piles | 杭の Line のツリーを出力 | + +### 備考 + +- 杭についてはオフセットの有無で杭長が変わらないように出力しているため、オフセットを False にした場合、杭先端がオフセット分だけ異なる位置に表示されます。 --- @@ -35,25 +41,32 @@ title: Geometry 部材を Brep で表示する -|入力|説明| -|---|:---:| -|Data|Load STB file コンポーネントの Data 出力を入力| -|Bake|各 Brep を断面符号ごとにレイヤー分けして Bake する| - -|出力|説明| -|---|:---:| -|Columns| 柱形状を表す Brep のツリーを出力| -|Girders| 大梁形状を表す Brep のツリーを出力| -|Posts| 間柱形状を表す Brep のツリーを出力| -|Beams| 小梁形状を表す Brep のツリーを出力| -|Braces| ブレース形状を表す Brep のツリーを出力| -|Slabs| スラブ形状を表す Brep のツリーを出力| -|Walls| 壁形状を表す Brep のツリーを出力| +| 入力 | 説明 | +| ---- | :------------------------------------------------: | +| Data | Load STB file コンポーネントの Data 出力を入力 | +| Bake | 各 Brep を断面符号ごとにレイヤー分けして Bake する | + +| 出力 | 説明 | +| -------- | :--------------------------------------: | +| Log | 変換結果のログ出力 | +| Columns | 柱形状を表す Brep のツリーを出力 | +| Girders | 大梁形状を表す Brep のツリーを出力 | +| Posts | 間柱形状を表す Brep のツリーを出力 | +| Beams | 小梁形状を表す Brep のツリーを出力 | +| Braces | ブレース形状を表す Brep のツリーを出力 | +| Slabs | スラブ形状を表す Brep のツリーを出力 | +| Walls | 壁形状を表す Brep のツリーを出力 | +| Piles | 杭形状を表す Brep のツリーを出力 | +| Footings | フーチング形状を表す Brep のツリーを出力 | ### 表示仕様 -- 床、壁の開口は反映されません。 +- Log は GH コンポーネントと同じフォルダに変換ごとにファイルとして保存されます。 +- 床の開口は反映されません。 - 平面でないスラブでは近似した面を張るため処理が重い場合があります。 +- SRC,CFT は S と RC を一体化した一つの Brep として作成されます。 +- C 断面の背中合わせは H 型、顔合わせはボックス型として出力されます。 +- L 断面の背中合わせは T 型、顔合わせは C 型として出力されます。 --- @@ -63,12 +76,12 @@ title: Geometry 階と軸をラインで表示する -|入力|説明| -|---|:---:| -|Data|Load STB file コンポーネントの Data 出力を入力| -|Factor|軸線の長さの比率| -|Size|軸名、階名の文字のサイズ。デフォルトは 12| +| 入力 | 説明 | +| ------ | :--------------------------------------------: | +| Data | Load STB file コンポーネントの Data 出力を入力 | +| Factor | 軸線の長さの比率 | +| Size | 軸名、階名の文字のサイズ。デフォルトは 12 | -|出力|説明| -|---|:---:| -|Axis| 軸と階を示す Line の出力| \ No newline at end of file +| 出力 | 説明 | +| ---- | :----------------------: | +| Axis | 軸と階を示す Line の出力 | diff --git a/website/images/Component/StbToBrep.png b/website/images/Component/StbToBrep.png index f0b6d2b5cc824f239c9214623df74945d821d3f0..0619c62e3a2e9f7567ce1dbaf3153891fac2a732 100644 GIT binary patch literal 17343 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 diff --git a/website/images/Component/StbToLine.png b/website/images/Component/StbToLine.png index 9f44f0d67cb75b7f62902bbb88795e956b9598b9..b9eb54b77a583b0fe67dad6720dfeadec6f1eb7f 100644 GIT binary patch literal 15644 zcma)Dg;QHiybVy?ic_?>1t=6R(o$TDh2Rt^?(V@IiaQi5S_tkgL5jP(7k7X8=Dk1Q z%_O-qcQW_x?%jL#{LVQW{!K|58-ol3003ai%1EffkIC@wA{q+(S0bb38h$`?}M zCHm5=B94IY#c}_nBCY9Grz6^|Rbe&Fi%HOnofyk$RP?d+QPA#~pF)TKkINtxOFW|4 zXtqX0reMO(A|)R*ey82NmYEz(6*t(caX(W1+5gvcIh01%B0a}=BUvBFQ^j)9v!_LIv|qJ_fsL*4;_Z>d zXQNFmO7o)Tfn7eFQn}yR)zj>_6H#qCTsm1OKeRT+`NH;aJ8JX#@7w3kkO&ga(pm%r z{jroxCNy;PiB+FRmyK?QnF^xqb5(@dLirS4_kHuGOeL3-Y5kc}_2iz7b3%02@2&nW zm%EDW26ftMzelkQGN%sIPjm&ZHzDo2N8y%O-p7<#9rj;N+wUVTwg)MXBVCSPYRULZ zE0tnJ%CX)}GNB=i=5+kx+G08yN-86}+q{%ZU{nkcW~!G(fI;K7oS*K{eI6#39NojP zAax$Ye2SUEJ&=-DCm;1D)!=!m6y}at5~%Ge*2Gh=e69JQBM~e3Gxp&e*RtuV6-7jMzQ*4t`dM&PccI}sO90pB!cI|gE7L#|<_wn9MK93#csM^bA(o~joV$}AX z#Z=CRSMRW?1(lF7w>9TRV~5tn4zKC2lqf_U)#;?7HBXkCW^NC%sl;#$O$Re2Tij6D zoRSq-b&Cz-+rIWn!Z5+Gn4Ix-8aj;vdm536y8Ow)7KXV>gN_OkeTo9CcOUn!{W+PX zWBxTeY=z)Zidy>m?fw&l_e}3#^0&sR{z~`U=HA}7LHxcRztwi16w%iQuR6ct=yX1d zUt3H{tUNplO^!S2_2pW^jNa-b`mN5gW}}%J;MA$Vm@sUN($aqHqfn;^pcXfqUG{RE z0IKf8)j>_O=W%+q$!LLYlcVILL$7IEiz}+t_CES9lFd}9WO+mPxfZN1k|c@O3gjeG zJDT)SI`P(#o!Y6rwP{3p$oH52_DF`#!IU&7w&5El zL}j3(>5?gw_rVxM-(WB*Q1)_@ZOhn>qs7uqR{G@;VwQ-Pk}yI3duC{<_Oe?nx9Jcm z+uas&c~;BK{&Q^mw>_L=7x+jRO{3#bi`HMCfGlVlHHSchS zHT3oA+O4OK$-UBX_irw3Fa{a2?{kRagW03fOqrUzNV7{s!!<#xTgMHxfO&SGSGit; z{w8}#Wo#D z*07qh`GE5E2*iG6zXWPnX?X3VX*<6OMX`@2n4q6DDzv^^HI2xER zemHr=Yj*f3k@ZQ~=qE0!IDP-s=k`nw%;f#&1_QM&Qnb56^3#LE8LPt^cWI3h^)7F{ zy-|blGnFlDE(4FM9A!dJfw^We{$l0I6IShlZ;2U>2N$OKq2KRup4Kimjzs-7^7MVL z*^`(->dLn#x#j1C6Z>UiBM%z#$$zG$PqDeF6N->1tp+EPv~OW3*N69wLrLtEJAX*U z_YKBtoJ;V3#Ntp07vSYHG8^|}d0y|lY~1FKwmvO>3cV z80I8=?*0vTSzdSgST61QpGoICApju(wr1Fk0)FXha|)(%DXrMx%Uw<-a14d3D{&yxlHbA61{>+>Rm zGNog(e%h#EFXYpuqK36+b<^QwK9IY*@lNSXy0Fb}Avf#Fkn5u$gKFbF+pW!FgUWiY zuyQWTzY_WD(uI?sad(>t7>VwK- zbmeZG*61gQ7tZB3p{kgD5r}f-r9D&nQZ$}F=kv6{-`t?3wzBp_Rr$tLKMk&zpm6R-IijO6%u-MKV64%6j9;hEWU|^7}2xoxv1-yK<06ra$lZNoS`s56vklsq-2Xxiz=1QWnE&OL^0|FL0<+ z38415`|^EMn*Z!Go$sp8kp>Z)w!l;Mh)(_CWo7$Zf=F{ZCnsMSeSP$5vr9|+gKaUD z?VQxe>*)zICk)bg>bkw}Kxet!w^P1w$@4ged^nSDl^OG$Rut_P2ESG5ZGv*IN4Dv( zrp4bomXN^9E=k_i$1_YCZUfKUN({mQGY*GlUG4Tw{%A@u$;uAy&!)qP+^?}zeK1UZ zD#5EVnW+s|$Vv9N=xC?sUf`JX$+AaH7twGEFD@=NCIQf`|F4!5%I!bm`=c)w)Ivt( zD%|;(GiQC?XXh!4ZDy5KGU+^}cDvGD5?E9st_p2A{}`7MR&f-(XECiRsiV_kMEOl0 zV*3w0_eT7OQut#%fSWI6ry&P_)0{j{k2OcQK;E!rkH}iXbMEWI^F~$;AW4yh@7+1c zGq+hgg3kl#|HcFP0~a+ikGs!0V2jywUE=v{i_>MZm&ND) z{;~f<)xMbNqC$QTf}t{2lmODv*mcI$%1^w0q){!ZReM5-Cj~GllR!$+91{!)cr5pi zF>*j`CvC)E#q{GH8^Hsw^*2qyYO_cl z$uw04jXQ%JY9oTR1YS_(vzmY{wY87mU3!h#@bAt;jczdj7U9cj{_PrC2kt{2Kb3&H z1gG%YUj2B6teW3=K(Kst(ps$pQm|kT&n0Z(LV3$hN&KfedUq9=(g=Y2NeB%iizs;f zw<#tO5d2>5-s^mmVdTl8{$;g(CA0SH?cv{T&si0pe)d;7^;rrjTme08~4Xw)> zW$NlneC#3@51!Rs33rzmU|9%9A6ibvrDNk(L&lD1L? zhDLFZuJ231aB#~&(K@T{<#j}Cez+ZpF4EJ3i?!`*fPg9{_Z&giQjL!?xOFz~e5q;S z_qN#G@@cd=T2d#YWrw$;RIlZRbeLLR%%|Dea;Cb;a;EsC%9h+L#^p%fmCVEYg)Gi2EoeiCd-vjWz>(UIhfmHMFdRB;ZTZh2O!t>u~hRKuD=IL zFVB%IxuNhG-Wn2~&&9UI#)aWX)8#hzW?up)fBp5zl3OQ*izL7Ovi6>bbSxGB<`CJ5 zS@7&D9GC)4Kexb1CTU#q82e(-E!SSK1rnAX9aVb|aGvSO7{aQ&x;*r@C(TIR3eLQZ z=#rlwdviZm<0#gv{UbnqgMLm(4o3f?;ia@C1&s`t|9mEhY;Aa-S#T5dtrI0VI`B>I z=Tc;1Uz|L=*_ZQ_8%hCl;fos?5yH+sNJgISf+|L-ejiJXa%->b%{%@Y^`FhS^v4ay_7f{NooW0bOny;e*FG=>t@t)g! z8a!|Q6#})YNsCxwc)bcZFxKDnw{%#}u-Yu%g`U_hj_1?Wxg$lsfh>Dqmbe_v_Fvlt zvbrD)J=>i9?P>b0oRQ~Qha`fL6T=S`(6F1ovz_^)!~Y~he;t1_>ibb(_F$@r*XGa! z8C14Eah|RWkvz*0QRPGi%r4ZJ5s-lEtmgPsaBgJU2tR14?u{}~LCJWURAJCQ`hz=zZ_q8?lFdx~-_Ehoj1#Va(2|_SY9LY%(5Z zS%GBa@+PM}vQYPW>xHXMB;5UmHQ$dOh+-qD1^@8yzqBGIGho;l_Tj28BSU>34w!r% z4vL22=t2Vm1F>Nb7sH%AUlJ)G$a5xt0A(_9wAyW+b=vjT7KslVYkq$oY_(=vQ{Zh< z$qyN++KgrELIxU|j%DkG;!=Z7SKF@P-7U6W(DBFsSPlH7@q|ypgeYSKV5BiZIebh@ zjbSkl&$nwcm3GwE|IY7h)S>=6$jsgjR&pq_#<3zluDX54u2sfP_@LhYs5v7DPw@<4LAzK75%V@TZW5SW!M!!_QCM8`;0gaq~m^<+?dOV zUDd5twNUQ7!jg1uMtkV7)#K86OyrjIXH`3#(3F6y^3p%Jx)(^H=p$iL4!iRAx|G?X z&Q6!8U9Sh?l3BgAhtHyae42>aw|+18Fy_B^KQRcIe?6Xdh%H-2y-ta=Od%3`QoWb1 zTx|1dkUcuRUH-_}CuTHRrVKH40*>)9mzJ%A1t=Z(f3-5f5TId@eP|Gn)4t@O0Hab~D;4<_e9I0IBnk=nGTnBbxyA}Vq5{?2SY+{-6 zoksdY#Y4eXQZ61a22B(Ib+UH7*;7{K)sZ^^gr7eAV&Vv)HXA(?fi=56H@jM|6`qDh zPp8-UG5ftdrSn+C2LuGfV}Vm!@6;9>?Cey>i8*x5Gb6^tUR$|MFIx3Iz0rM(miI=h zEKxMhvtlF_KKW>%;8K3)&iV2orWub;ioPVq6an)U10rO<4msDpJzX=HDV40?^(z8& z&7Gzhb}lwwQ)7ESvmdYdeGA4U;oBe&#i5+kb6ZIQ{x|tA_r{KPQVc*XuE)-6KDYPj z?QZ|PKj2SOC%VN7g2t%y^gJ$?OHmYLzp#=0ydw)3lPRR;ax5=FjX<*N3BleC^7)&} z#j27gQN0N!hA!4x7z-*&Ha^P4N;^hdKtUez~%Y35C ztHKE%t`|(ULm=ifY`gAf;}EB|U2aTrmK$Lx6Xq3DBl0+pH~lSlVV2|bqx^%LAw!*p zIRfU+$|e{bPO-h%!%qlxE*Eep?|9MO$@>+mG2Mem)P{z>zQ^M;09DCrLlLEQ209J_ zW0EosQG<3mI*`c z=Jq~qyN#b-`OJ#H-p%%x5y}y;9bZcB_LeB{v#4qrF%WF{IeyQ;N~GT7 z_TPdr?YA7SlcqOF#5{}vNitXk;9PO!ndfkh=8pR|l^f41G;k{^CB^QDPVsj-SgQVj z`zn)CW@ZZMUmlGjJ4G zYBr-MhK691{|La_8_ThqrWZ17G;fQAPbZ(?|Gtfh<)FqMMY zLa!=!hEp;MG$gj?h}QQxC$;+O*!LLR2@v8vcR- z9WM*>@wymfQtZdEdT@Anqc%HGB$PZ-)w(3aX7*DN@x4G63p50I0J@BA&$om!obb=_!up^`x$qzeIZC<5np##T>HZePx zLq!*YKtq+pUdNw5MiXUYMQ)%%Zr(gYRO@_DRY7L&bI+5`{}x5{Ja;a&!Ahy<&r{t3 zr5i+0%h?LM7IN<@r$KL=qw=%8oFAT4u|!KW&d#S%frN&+#tXbM34+|My4gE0Idwy1 z6qLoz3r9GXAD>XbnRjXX@MQR5--;keb%%)Y7F(A6sK&WmVh3E`LQ~ht^l%IHPkOi& zkX`*SA^AO8``WtfgKWK!19dumXSL+_O3X#A92Th-0NzGwqWQ zEwNX)bRRB#tNuzaPq^4Acde7v$eBvt+5N@y{$i)sXX?{G3yGgGl%GKI$v`eY0;Pmh zxTbn}V9F9pZ4{YFL`G=QZn@ZjBcn%UF_*+WP=&TI!`bnGy zqEofuq|7MSENJUa)J)3RJS&>_lwH1W)+Qo)v$pV3+C46RB$z}kBD!z&RJA{zd`f8i z(n63bn;U?9H8jjw?2wNVcZty!ZVNHisMKGXt!nKg?ljsOWHo!6tPuC{idj4=oDBY2 zm91Nced$g0Iuz-kQ@B5eQESeWYADWP8A{aR%gW^|ZtlRBElYv-B~Qx)B!*f-#8x)* z&|Fy%16>$>OsNK2TD>Elywm@_NB*ULg2|ttc^T10zan@`?*mM*C5*)lRw&Z-0vh3V6of)Cu%ra^#sqk=}=(e zoE?@`Voacf0zOYWLQ(F60GP-^w9v-ba!LuNz|60#WQaVUQBx4!MBVL!iD8bYv+x%_ zs*&-A(qSI1pRFMc-?YN04e%s4;^?HKQfVmvQi8c0fDtZO)S|)^;FB_cV_x&|bv{EH zvMLD?%4Cgw9AK}_-e?x~9$jvLnCKpu4=TKpH!z0)OtedMyJCe%&X@@#dqs2FK_q=? z6^GyPU=?v2>q1P4^qo+NUC5c0#2*&<4SdU6PA!d)*j_%IJ!hE^<~Jr3g(?MgMBtn^ zk}qE(ZeaqoXX6yHQ^z})KOnldA%hxhS9olf1=LckN6Qa}a!x_b9lWiRRfty8amTi2 zIMxNz`9#;X6`L1MV2PLPgb5+5I~kI09y_yK8CAP%EmA})SxJ_}{F z3SGej*0EO)p>C1Wnji1@QQr40_KJu{mltJwZ`KP-@7DS6u(+JA9|7U({H)Ff&Lq~s zR7Nwn&C5lzD*%~R1;%Emfm>?xSakyEY(lbvdjqWB-gjuP`sJjr%=8w_N^49`qRdhP zuSow8HSB=a_unnAW0pXLlOn5?bndXwsc;du#c)|~$zO~+r%2ts(ZNaw zx~2%ib|2Ohc_9zEiXFC{E6k~`mSJ<{S+$}46s@EuR%TfBA4jTBw9;+Os^OdQJsZdE zjQ7v7h~K}2hib20+^@DW;!E7I?QSFAg z*~DRn4!y3)l(j?i^eydGPMOfiyE3C@Ps_vdVg-X3&H4I2j#vAP($AhHDByi?I3q?G z@~m83-nh$Q;$&<_E>a7z#d$&>k#=3YWznCayci=4kw)dwg_=TR*v|f0Dn$~TN`YKn zJ!VBq zd}%^>cLu7Q4{Il*Gb*0Fh%K~EH=FgV0vtbG4A6)*abza234kkxHMcdZ0wfR?pdXNc zDLLErO>o6kR)eZZDfgh;xp52$gZTvlLLpRp9v?1!9Z6}fGA`296DlGz{Qj)MI*9_Z z)*dXG!XV{Wgt=BspNg;@f_IiLFzrc4x0`+SDyGZ|er7mskFZJq{=4B5@&=lzTCsjv z%5R%-(TKrZu$CaCRbK6TF_!!Aon+?jXc`qb%v$SDgb95c9CJ?KY&?vk=Utv*3;OfE zBa`Mro`iKTuE%l2fO#&Q;KFK7>1Ahl*mV1sVDX3b%e5MVv`|Hmc1M)lW%nfphpM<( z(O@YG{JQ%`oX*Cu3iZA!d`hrJ*&I*a+dd8kY)Ikx*3Kdo@KyR@Fe$(OsXBzU{4Y_V zpyRift=|I<>pyjUypDd<4JgJw1>Um#TRPpox>f6h_%5n7rv7+msHgfh(%9vMUOH>B zL>wl^qcYHS5GyvumBj)8MPOzK`e;{F5o|Bk$j6+FG4t3_3M&6jp<7Z!)?J|KxKG#? zaFnUg7a;=uk)wADT+8-x^bu2++v0phc&@E9#2djF_#Ki5mrL31V%G0K_Fw1?zJYEQY^9PwwI+U zhC9CWv>$NK6|U5ys(MO4K_9M?^F1|K{`!T7h64Z;L;qy~lt-O>h1}`EOSXTf&#$Dn znYATe7OLgHE3y1_8D4qM0?Ynb%JsxKxKW8chRV`tu4QvpR*6ruq<;2Km`EgBL-FYZ zv>U<8;P*=Ee+@5$L){A3#UF@7&wB|%Dzb6tQEFKY+FRka`|g1am4Vp-I1tsZh*2Za^mu%zuWHh~L2|Ho|XxOacKw zd^CVTo#hM`c-cR=qQUdp5=jVg3-BrU?vu;mHXf8hicpl@tWHkoSg24e)2i-t5k$1; z4Vsw?W_1gcPGa=a2rfjQsq^OFzDSwWb!47urjrx%$g|ycIJA7F5{eUR0UiFt5qSMJ zg6*Zgb6U=-^8Do+=|?F7idevx z=2~%T^Utir6UFUveGLM{)MA6R#q7nB4D!TtN0qI`+Ps0Z!J`5{Mlv@sFfnI#*fbRb z-wXTmP<1$7mv$kJ^cN}Sl)zoav}m&}v^0k08AOnC9XXmmG8h7*1cz}8kPJw((5JQPc1Z#?uKWexB zz7vE+C9Gu|3O)*#B+Oh`>Frxmjw29>Y*uPxj+XVVsotQ7IOqS6)EjZq$kqCqv@1tu zDwL{J@!aCI`?d{}wJDO~u+L)j|OscrJ1P&3fslZN$?OQFr$mkMoOqdJWH&l_NS zBmrW>DoC(pCrp-{5T6ZzK~1Of%R6&C%LF8({nk=}4~G@wa=fcslU;ea#g8UWHj05U zr;gVWteoR_;Y(k&zdz9yIlSY{!UOzgApJ{z^h4480^)49q`Wg+)F(iE{QGe%_4W1* zSU43&WddP%(Oujr{5%A5a%{}$j|rCy)NW#v;Tt|Exm zaK9+w)7HE$bqzUIAB0qwc6@4x7!xV~OM)>l^DDbzdgynCmL2PQKnFMVUqj&n%?jI@ zk%O;bo>Oao7k*#r)%jBg8k;*>M!UCLn-pMS{A|!#@$8l9q zp<$tWf%FYy7*Kh06?240C8+l{sph}HnJA~B-U%uCW?WeQ@lxOXcOnkHy*Xs5*feg_ zh=t`|6k@~wD08%_Yy>~ohCR@C7a4()7IBA?i?S>xc+claJ!|PX^yQz1-V)nmS(t$X zugsh}a=>%aWhmuE3t?$Ztj5F)#=9NA1%otPljK)LKRs3t*=DGw?;6(JM6GmPt)>Sh zN2XTaB(Fvdw0h{Hd#$*ub%Kyvys!Y<8}L;iBMZW>Uz+ElAZiK$JoL9bKf2%h>r_>p zj7$@dgCXg=DpyZ5I(s8?2D5ay4bfOY;)B&I*xHz~#Z)1$)LYM)r~62k^>v!-e+yH! zf?va9Fk!SdVVzzmLd5S_PI%Fbw!i>Pu25C4t9_NJt3^cO0|jd=+N%jS)^6Wc6rqGJa7kL_XOBn_^*5?BrIXAxOiXF_E z5g>mO#~t(nC#Nv~U96?zEvuZ`6IGVnoce80aPj2a+TreKmSZ0R_+-dS;yl_{_S7cP zvzJ~Kz%@Y47Vwb;5}f{ZQS^bm4dXz|og7BSbwy5+aiY)l=GXV6bL3p%m%AxWvX8cT za1^%%b7%2-EX+FtF?0d%uc#7b9ml~~2W!l~vLnPh17t^P?z{2Q0FfLy`;7nTffj=( z{s@#3u|(jlAN%%aMk7aR-%#1Mze$;@YD+_O`LiYqtuU~g=wB(c3Y`xMGve8%Sxm1! zZfM-Q8mQ(^wCtS9#K^q@MDH5HdXr}SY$P|qL znBRIt@Ph4u(}eU$Qhi0#ZC3bfwn)iLl3xODPv(|ReG8)fY`8NK`rdlPnugX9uf*XH zGnm?)xy5@%NMA+Q-f@ldWc z$#q;a7j4a43>{Ga5T&21vvSN9r0W>}An3Rk$8DN8ypuS*0cXl)IJr(IqGiqb4JE(w zQ@bBT3b*=L%|V}Ck;?nmp1eT&bTN|RY)S^z`6@$$JH~Yz+*EeI2-~yY=67x_#7?NVAJ#rGDo)ppEV)!G zGOd*B$|4|F48{qnSJ1%<`{Z{7T;wW}ab--0zajPm=Qj3!vi&WAh@d9g%sZRPCVY)S z7_(6Jr%g}d%ODHVSEnQ3tC1g7q7<2|8VLCPNjTY1-AbyVuSl{(93|$vw>~HfQmwksYN58Xncpkug zA8jL;$@L&VR!k`_bX>?sn@mh8#t&y;rXnZv-fDo;CY7SEV(4_)_g*=Z71s6D@y1t` zX6BV(ftXz&$QAo#l|uaS_Q)!ad=nF>%*R(!i2!coV@3k}g35gdTp!KMLSB3{;@|#5 zqf_dvK9P(wXf#htUs+nFi%FUe3cq^ti*V9^zCBd#XH1T+0i0 zq!0mW#!@*tEN_WsDhUSM%6$zT+}Wdk2bO{@-gCm_C?~LqVF79!2JH%hPTSwMq^@V` z71@Z`ZgQ6BMukA?oxfz&c1pjn5Q8fm2)5^IbPlJaE95kGgp-tVnI?xF+&d=Asp&cr zx*V_mv1l4z4|FaP0Oz0^@#Iin*%Za=uNF_ey?FYcx28C4KopG9>dmdr8r z3pVikj$5Da0 zLAEF8An>E~b}_zI6yv9pICzdkB!la$*};aO0h^U!j+J&xzlPfUPj z0ku>Kweobz3ynuI9?K4AZ{C8f{B$Vt_e7dQM+_R(LB}D9#9ut+J#x$?a*tRb8Vr+Z z*_e8)rC`<>K56j^5TYip01HY_4oux#H zOl}omF;ZBF3)?2#GP@)xldB_RNjC07DK}>!K>#1#X6goGuu9X?5CE>DjTRGo7-RV@8f>eWQE>j&6vzgnaAk&?(Xe*O5ogj zmtz6?&&y!n28kc6RDj5YSmevSQrqLspt&jlNKWDR`2FSN)jO$zrtE!IJc_-N{QzT1 zVftutPLjOpxdhc9OV<)?<5vW$>^-4mCTXDwtzdXFgM(yr>IWSDHR?*d-yYoJf(rb0 z{Fzki+qUg2J8d3DBf-xLiR!VXC;)k8FV_pzTWh05ZYd2g;_<-zXr z4oic4a!{C$N^(q6aVIS)dtVc|QBk2!FgY^3%p+pekWU+G!Ojp+c`pk$Giaf!R3#~h z`{27Od_}_U|I}PmW_;POs%oi1xg>=F&fM8SQ}EE^JeP4I-=CbJ6!t&qyoibdF3vq{ zV#&xr9ax0en=n{j2e!kp#0CDA)DxLXO}pG$#OtB$iiHEPx?q6SF(jDf12p|0SFPMU zj=AU-1H8iqs&fHyx?vmQ*(!XX_V?|*O33~CkH8es-p=rlU{_I}W@F&Vfzvs(-~d?D@a>e&h7F|CQCqHo4;R{TU%UCJyE zDEiM546kP>Ab;;QgvV~kg{mb%@2Zgcp-bXc)c)1S^YYq1uDN`XV%W>tofoMyuNLqb zf#)iiF*hYhrx6D)V;lReE7n_?uBCRL76dACr4bbIkQV0yqs{#PT+dE9#19NO0AlQ+ zK~4JF3}IzwfeRuLY`uC2@-G>lT~U0UfmueH@9_L3lW`WtO$_5~Ussm`uM9I#y)l7HtXC#hc^!;-F~}(h>L%O{rC(O*{gxA? z-&)Y`A_AS6Cs!8C1t>mmXGP}6=ba7 z%;FpS2`Q#;88pgp*&l4I)k(WEwh1oCh?99*U8+3l;$ycl^aw}JS*5}QZ=b;BMJ!pf z{B#^6OjC0C7#_|<$3sm3PyoNPIwENNG|lSUJ^?lYp!-PJp6OG7PYUI}@X)ev6OArsTVM18m+2P(vv{?yhc zQ#B^>J>`-9hDh93avrC=LANfSM zRwofbd5*xLMMH*px@%Q{3K~qi*(8n~L+zB0=_P{!9af!m+q<^k>uVGb7$y!5ZyO1J z6^8VA?8Gxf;!AsQ>ec7L#s4QCr7NZor}Ex6aEk=rCx_tKpBR22XNOJua#d4S(il^n z;PCdj@Q2TkK7>1Nh(?1{_a_+}mDJ+L3=>>==NMC@;m5Y$cVdcoM|yy+Qw8++r90*3<(JSm%lX?UXZdQ_*f)V*rJCLTV66jpY=DHV&1(>b}%>{cUeRUr4(Fu4lfoJ=%|wGN4%O&!wN@&j`th_>;xfR32huW4v=(Q-AwvF|2fX}NrZO|C zT@KZxC^I>@sBh^S&O!p)Q!HX5y}?&UKyx^y|Ah#2d=tJ}K!S&kPtP@;jw_i{Zjo*f zCqDqOnrH|k(-gQ>9j{ihNaigOrHJoUklf%9Am5ehB8>lL86^}QlGWT*m z%6l1GJ8ZRz7C?&hotVZ1H@Y_kSk8vW8LNyVO2&4)!y~utmwMBzo%^*{or9@fF#hqB z4iR&4vL+<^r}IMu2KeOk4Rn7=rj87SBKqk|W470ksNMcsBIx+-zMf3%;g`zxV(BF@ zLNP< ze}%+{;cQx%CeH6F*mj_T#{>1pyuF_+R$H5(4|l0XNW|2ixXpR+R08j zEvJj)@caOgS1&E;e6!N09fb;M-2If`D<+Do-N(gRk4QYL0-H-0sQcf=eSzepwb*;z zW@n2jD4rGSg2Ixf)dwaFCZQ0oe1+0d0I=N<6Z|(k=F2g&RVVr&PDn9xBa6iu$4MdI zM3%c|nHDnzf=jn$A;nA!7wX(+gU+x?s;Y%zexC0f1-QC+{74f8#msQ{;X1hfFZ!%_ zN;>|kMUsK{v)=$7nFD=J2bd10^HTU*Kj4auPX7F!A0^Yn1K$EtQxYNm3=km34Yve$ zb_;W8RTsoPU)lYx2WYjtMO6Oy9BpwhOal0Jpo;4N*Qv6D83Jxe;JHa_t)7tkO_ubo zXRvgb_AE?l{=a-f^OCri#Gjm;uZ42S<4$8Yd<=B?h*et?H^)W?g>xI+SsFkszY@}p#9-#eq3u|oR3I{-VoJ6KXD8tm5W zxdyzanIT_k(!WnYa3f0{w)))|G4R*_up9mXw<};DdXVy6ig%dlnvG?}))(-Rw;OKY z>oq$sSd+PAYz|ey<-(@3_f9~-{JMCUtO7{hETBxqB+4mjD$8jkl2p%F4D(d&xsbl9P3-dGWvd=Y!JG|t^`Fl5uPako$GHdYbM_3kGNt^9XoT?SF9(ImcDC0 zZ$`8GCab)0fNs?H5oZvh)vr)_SPE9OWgc7W|rh)Fd)hEEAyjVs;7&Nh2Xk%DN z^(67g2#D-CUjzL)`@SDluICk6iz}u1su9{%4yX#QrK2m} z#vaqhMP*h^?>2rd?^xniNyV5(YvkQ#JX7s)4%b>4hBfMSO(%NhcfseVni7V1|75b^ zljIN9Ts2B~`93(at{)i;%BInMO9$DHhug)Wp<*7@j_^G)I-~XoBweYQ8$Sl)weqF0 zVw`==BgK`OGaz#SAgwukPnB^@)fqazPCrU_S1U5HV3@tot}%cIV2Nz)d0`2_R0+$5 z3HQ!+$%eabe7!rojCEG7`Q4xhr&a_*jO)CBNJa$_&#Mop=MXl#)z-M`)UDwv0C8r2 zsea)1&RNE5P72|hwG zl7SrM%8rM4GTw3$3(-nAcp)Fv34#t^1b`}G*Aan)XS;(5I)VB=vWjH4pa(A6KQ-r zWA(?`49|l;!r|??e`MFri=G2n0HCzLSdM^Tq2B7w1uuRmidg^ZBe6NiT8NEg{ofv8 z6{e5$yoJ_=4A(gB=icOC{kLQ7yq*~Ioz)X@@8Nrelir)uG1d8-8o&R-Y>346Wx!I| z5^1>qa{xR?4+{7>lRXWO)BD5Y^o}UAuSkanh0G%RICt>v&H!0SC5Z}g!+`$*5>uL3 literal 12191 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 Date: Sun, 11 Jun 2023 20:18:20 +0900 Subject: [PATCH 5/5] Update packagejson --- website/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/package.json b/website/package.json index a36f11ee..c305fc34 100644 --- a/website/package.json +++ b/website/package.json @@ -1,6 +1,6 @@ { "name": "hoaryfox-website", - "version": "2.3.0", + "version": "2.4.0", "private": true, "scripts": { "docusaurus": "docusaurus",