tbd 3.5.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -1,121 +1,121 @@
1
- require 'matrix'
2
-
3
- class Matrix
4
- def []=(i, j, x)
5
- @rows[i][j] = x
6
- end
7
- end
8
-
9
- module Topolys
10
-
11
- # Transformations can be applied to Geometry. Ported from OpenStudio Transformation library.
12
-
13
- class Transformation
14
-
15
- # @return [Matrix] internal 4x4 matrix
16
- attr_reader :matrix
17
-
18
- ##
19
- # Initializes an Transformation object
20
- #
21
- # @param [Matrix] matrix A 4x4 matrix, defaults to identity
22
- def initialize(matrix=Matrix.identity(4))
23
- raise "Incorrect argument for Transformation, expected Matrix but got #{matrix.class}" unless matrix.is_a?(Matrix)
24
- @matrix = matrix
25
- end
26
-
27
- # translation along vector
28
- def Transformation.translation(translation)
29
- return nil if !translation.is_a?(Vector3D)
30
-
31
- matrix = Matrix.identity(4)
32
- matrix[0,3] = translation.x
33
- matrix[1,3] = translation.y
34
- matrix[2,3] = translation.z
35
-
36
- return Transformation.new(matrix)
37
- end
38
-
39
- ##
40
- # Initializes a rotation about origin defined by axis and angle (radians)
41
- #
42
- def Transformation.rotation(axis, radians)
43
- return nil if !axis.is_a?(Vector3D)
44
- return nil if !radians.is_a?(Numeric)
45
- return nil if (axis.magnitude < Float::EPSILON)
46
- normal = axis
47
- normal.normalize!
48
-
49
- # Rodrigues' rotation formula / Rotation matrix from Euler axis/angle
50
- # I*cos(radians) + I*(1-cos(radians))*axis*axis^T + Q*sin(radians)
51
- # Q = [0, -axis[2], axis[1]; axis[2], 0, -axis[0]; -axis[1], axis[0], 0]
52
- p = normal.outer_product(normal)
53
- i = Matrix.identity(3)
54
- q = Matrix.zero(3)
55
- q[0,1] = -normal.z
56
- q[0,2] = normal.y
57
- q[1,0] = normal.z
58
- q[1,2] = -normal.x
59
- q[2,0] = -normal.y
60
- q[2,1] = normal.x
61
-
62
- # rotation matrix
63
- r = i*Math.cos(radians) + (1-Math.cos(radians))*p + q*Math.sin(radians)
64
-
65
- matrix = Matrix.identity(4)
66
- matrix[0,0] = r[0,0]
67
- matrix[0,1] = r[0,1]
68
- matrix[0,2] = r[0,2]
69
- matrix[1,0] = r[1,0]
70
- matrix[1,1] = r[1,1]
71
- matrix[1,2] = r[1,2]
72
- matrix[2,0] = r[2,0]
73
- matrix[2,1] = r[2,1]
74
- matrix[2,2] = r[2,2]
75
-
76
- return Transformation.new(matrix)
77
- end
78
-
79
- ##
80
- # Multiplies a Transformation by geometry class
81
- #
82
- # @param [Obj] obj A geometry object
83
- #
84
- # @return [Obj] Returns a new, transformed object - nil if not a geometry object
85
- def *(obj)
86
- if obj.is_a?(Point3D)
87
- return mult_point(obj)
88
- elsif obj.is_a?(Vector3D)
89
- return mult_vector(obj)
90
- elsif obj.is_a?(Array)
91
- return mult_array(obj)
92
- elsif obj.is_a?(Transformation)
93
- return mult_transformation(obj)
94
- end
95
- return nil
96
- end
97
-
98
- private
99
-
100
- def mult_point(point)
101
- temp = Matrix.column_vector([point.x, point.y, point.z, 1])
102
- temp = @matrix*temp
103
- return Point3D.new(temp[0,0],temp[1,0],temp[2,0])
104
- end
105
-
106
- def mult_vector(vector)
107
- temp = Matrix.column_vector([vector.x, vector.y, vector.z, 1])
108
- temp = @matrix*temp
109
- return Vector3D.new(temp[0,0],temp[1,0],temp[2,0])
110
- end
111
-
112
- def mult_array(array)
113
- array.map {|obj| self*obj}
114
- end
115
-
116
- def mult_transformation(obj)
117
- Transformation.new(@matrix * obj.matrix)
118
- end
119
-
120
- end
1
+ require 'matrix'
2
+
3
+ class Matrix
4
+ def []=(i, j, x)
5
+ @rows[i][j] = x
6
+ end
7
+ end
8
+
9
+ module Topolys
10
+
11
+ # Transformations can be applied to Geometry. Ported from OpenStudio Transformation library.
12
+
13
+ class Transformation
14
+
15
+ # @return [Matrix] internal 4x4 matrix
16
+ attr_reader :matrix
17
+
18
+ ##
19
+ # Initializes an Transformation object
20
+ #
21
+ # @param [Matrix] matrix A 4x4 matrix, defaults to identity
22
+ def initialize(matrix=Matrix.identity(4))
23
+ raise "Incorrect argument for Transformation, expected Matrix but got #{matrix.class}" unless matrix.is_a?(Matrix)
24
+ @matrix = matrix
25
+ end
26
+
27
+ # translation along vector
28
+ def Transformation.translation(translation)
29
+ return nil if !translation.is_a?(Vector3D)
30
+
31
+ matrix = Matrix.identity(4)
32
+ matrix[0,3] = translation.x
33
+ matrix[1,3] = translation.y
34
+ matrix[2,3] = translation.z
35
+
36
+ return Transformation.new(matrix)
37
+ end
38
+
39
+ ##
40
+ # Initializes a rotation about origin defined by axis and angle (radians)
41
+ #
42
+ def Transformation.rotation(axis, radians)
43
+ return nil if !axis.is_a?(Vector3D)
44
+ return nil if !radians.is_a?(Numeric)
45
+ return nil if (axis.magnitude < Float::EPSILON)
46
+ normal = axis
47
+ normal.normalize!
48
+
49
+ # Rodrigues' rotation formula / Rotation matrix from Euler axis/angle
50
+ # I*cos(radians) + I*(1-cos(radians))*axis*axis^T + Q*sin(radians)
51
+ # Q = [0, -axis[2], axis[1]; axis[2], 0, -axis[0]; -axis[1], axis[0], 0]
52
+ p = normal.outer_product(normal)
53
+ i = Matrix.identity(3)
54
+ q = Matrix.zero(3)
55
+ q[0,1] = -normal.z
56
+ q[0,2] = normal.y
57
+ q[1,0] = normal.z
58
+ q[1,2] = -normal.x
59
+ q[2,0] = -normal.y
60
+ q[2,1] = normal.x
61
+
62
+ # rotation matrix
63
+ r = i*Math.cos(radians) + (1-Math.cos(radians))*p + q*Math.sin(radians)
64
+
65
+ matrix = Matrix.identity(4)
66
+ matrix[0,0] = r[0,0]
67
+ matrix[0,1] = r[0,1]
68
+ matrix[0,2] = r[0,2]
69
+ matrix[1,0] = r[1,0]
70
+ matrix[1,1] = r[1,1]
71
+ matrix[1,2] = r[1,2]
72
+ matrix[2,0] = r[2,0]
73
+ matrix[2,1] = r[2,1]
74
+ matrix[2,2] = r[2,2]
75
+
76
+ return Transformation.new(matrix)
77
+ end
78
+
79
+ ##
80
+ # Multiplies a Transformation by geometry class
81
+ #
82
+ # @param [Obj] obj A geometry object
83
+ #
84
+ # @return [Obj] Returns a new, transformed object - nil if not a geometry object
85
+ def *(obj)
86
+ if obj.is_a?(Point3D)
87
+ return mult_point(obj)
88
+ elsif obj.is_a?(Vector3D)
89
+ return mult_vector(obj)
90
+ elsif obj.is_a?(Array)
91
+ return mult_array(obj)
92
+ elsif obj.is_a?(Transformation)
93
+ return mult_transformation(obj)
94
+ end
95
+ return nil
96
+ end
97
+
98
+ private
99
+
100
+ def mult_point(point)
101
+ temp = Matrix.column_vector([point.x, point.y, point.z, 1])
102
+ temp = @matrix*temp
103
+ return Point3D.new(temp[0,0],temp[1,0],temp[2,0])
104
+ end
105
+
106
+ def mult_vector(vector)
107
+ temp = Matrix.column_vector([vector.x, vector.y, vector.z, 1])
108
+ temp = @matrix*temp
109
+ return Vector3D.new(temp[0,0],temp[1,0],temp[2,0])
110
+ end
111
+
112
+ def mult_array(array)
113
+ array.map {|obj| self*obj}
114
+ end
115
+
116
+ def mult_transformation(obj)
117
+ Transformation.new(@matrix * obj.matrix)
118
+ end
119
+
120
+ end
121
121
  end
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -1000,7 +1000,7 @@ module TBD
1000
1000
  model = "* modèle : #{ua[:file]}" if ua.key?(:file) && lang == :fr
1001
1001
  model += " (v#{ua[:version]})" if ua.key?(:version)
1002
1002
  report << model unless model.empty?
1003
- report << "* TBD : v3.5.0"
1003
+ report << "* TBD : v3.5.1"
1004
1004
  report << "* date : #{ua[:date]}"
1005
1005
 
1006
1006
  if lang == :en
@@ -1,6 +1,6 @@
1
1
  # BSD 3-Clause License
2
2
  #
3
- # Copyright (c) 2022-2025, Denis Bourgeois
3
+ # Copyright (c) 2022-2026, Denis Bourgeois
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -530,7 +530,7 @@ module OSut
530
530
  mt.setName(id)
531
531
 
532
532
  unless mt.setThermalResistance(r)
533
- return invalid("Failed #{id}: RSi#{de_r.round(2)}", mth)
533
+ return invalid("Failed #{id}: RSi#{r.round(2)}", mth)
534
534
  end
535
535
 
536
536
  lc.setLayer(index, mt)
@@ -546,7 +546,7 @@ module OSut
546
546
  k = (m.thickness / (r + dR)).clamp(KMIN, KMAX)
547
547
  d = (k * (r + dR)).clamp(DMIN, DMAX)
548
548
  r = d / k
549
- id = "OSUT:K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
549
+ id = "OSut:K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
550
550
  mt = lc.model.getStandardOpaqueMaterialByName(id)
551
551
 
552
552
  # Existing material?
@@ -928,7 +928,6 @@ module OSut
928
928
  if u and a[:glazing].empty?
929
929
  ro = 1 / u - film
930
930
 
931
-
932
931
  if ro > RMIN
933
932
  if specs[:type] == :door # 1x layer, adjust conductivity
934
933
  layer = c.getLayer(0).to_StandardOpaqueMaterial
@@ -944,27 +943,7 @@ module OSut
944
943
  return invalid("#{id} construction", mth, 0) if lyr[:r ].to_i.zero?
945
944
 
946
945
  index = lyr[:index]
947
- layer = c.getLayer(index).to_StandardOpaqueMaterial
948
- return invalid("#{id} material @#{index}", mth, 0) if layer.empty?
949
-
950
- layer = layer.get
951
-
952
- k = (layer.thickness / (ro - rsi(c) + lyr[:r])).clamp(KMIN, KMAX)
953
- d = (k * (ro - rsi(c) + lyr[:r])).clamp(DMIN, DMAX)
954
-
955
- nom = "OSut:"
956
- nom += layer.nameString.gsub(/[^a-z]/i, "").gsub("OSut", "")
957
- nom += ":K#{format('%4.3f', k)}:#{format('%03d', d*1000)[-3..-1]}"
958
-
959
- lyr = model.getStandardOpaqueMaterialByName(nom)
960
-
961
- if lyr.empty?
962
- layer.setName(nom)
963
- layer.setConductivity(k)
964
- layer.setThickness(d)
965
- else
966
- c.setLayer(index, lyr.get)
967
- end
946
+ resetUo(c, film, index, u)
968
947
  end
969
948
  end
970
949
  end
@@ -1,3 +1,3 @@
1
- module Topolys
2
- VERSION = "0.6.2"
3
- end
1
+ module Topolys
2
+ VERSION = "0.6.2"
3
+ end
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
data/lib/tbd/geo.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
data/lib/tbd/psi.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
data/lib/tbd/ua.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -1000,7 +1000,7 @@ module TBD
1000
1000
  model = "* modèle : #{ua[:file]}" if ua.key?(:file) && lang == :fr
1001
1001
  model += " (v#{ua[:version]})" if ua.key?(:version)
1002
1002
  report << model unless model.empty?
1003
- report << "* TBD : v3.5.0"
1003
+ report << "* TBD : v3.5.1"
1004
1004
  report << "* date : #{ua[:date]}"
1005
1005
 
1006
1006
  if lang == :en
data/lib/tbd/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -21,5 +21,5 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  module TBD
24
- VERSION = "3.5.0".freeze
24
+ VERSION = "3.5.1".freeze
25
25
  end
data/lib/tbd.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
  #
3
- # Copyright (c) 2020-2025 Denis Bourgeois & Dan Macumber
3
+ # Copyright (c) 2020-2026 Denis Bourgeois & Dan Macumber
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
data/tbd.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.metadata = {}
30
30
 
31
31
  s.add_dependency "topolys", "~> 0"
32
- s.add_dependency "osut", "~> 0.8.0"
32
+ s.add_dependency "osut", "~> 0.8.1"
33
33
  s.add_dependency "json-schema", "~> 4"
34
34
 
35
35
  s.add_development_dependency "bundler", "~> 2.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tbd
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Bourgeois & Dan Macumber
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-09-12 00:00:00.000000000 Z
11
+ date: 2026-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: topolys
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.8.0
33
+ version: 0.8.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.8.0
40
+ version: 0.8.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json-schema
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -166,7 +166,7 @@ licenses:
166
166
  - MIT
167
167
  metadata:
168
168
  homepage_uri: https://github.com/rd2/tbd
169
- source_code_uri: https://github.com/rd2/tbd/tree/v3.5.0
169
+ source_code_uri: https://github.com/rd2/tbd/tree/v3.5.1
170
170
  bug_tracker_uri: https://github.com/rd2/tbd/issues
171
171
  post_install_message:
172
172
  rdoc_options: []