@@ -69,6 +69,8 @@ def get_lineset(self, glider: Glider, v_inf: euklid.vector.Vector3D) -> LineSet:
6969 line_type_name = str (self .table [row , column + 1 ])
7070
7171 name_or_length , trim_correction = self .parse_correction (value )
72+ if trim_correction is not None :
73+ trim_correction = trim_correction .replace ("!" , "" )
7274
7375 if not len (current_nodes ) > line_level :
7476 raise ValueError ()
@@ -86,7 +88,7 @@ def get_lineset(self, glider: Glider, v_inf: euklid.vector.Vector3D) -> LineSet:
8688 else :
8789 upper = Node (node_type = Node .NODE_TYPE .KNOT )
8890 current_nodes .append (upper )
89- line_length = Length (name_or_length )
91+ line_length = Length (name_or_length . replace ( "!" , "" ) )
9092 column += 2
9193
9294 line_type_name_parts = line_type_name .split ("#" )
@@ -109,13 +111,13 @@ def get_lineset(self, glider: Glider, v_inf: euklid.vector.Vector3D) -> LineSet:
109111 return LineSet (lines , v_inf = v_inf )
110112
111113 @staticmethod
112- def parse_correction (value : str ) -> tuple [str , Length | None ]:
114+ def parse_correction (value : str ) -> tuple [str , str | None ]:
113115 trim_correction : Length | None = None
114- name_or_length = value
116+ name_or_length = str ( value )
115117
116118 if match := isinstance (value , str ) and re .match (r"(.*)([+-].*)" , value ):
117119 name_or_length = match .group (1 )
118- trim_correction = Length ( match .group (2 ) )
120+ trim_correction = match .group (2 )
119121
120122 return name_or_length , trim_correction
121123
@@ -164,28 +166,63 @@ def insert_block(line: Line, upper: list[LineTreePart], row: int, column: int) -
164166 return cls (table = table , lower_attachment_points = lower_points )
165167
166168 def scale (self , factor : float , scale_lower_floor : bool ) -> Self :
167- offset_2nd_level = Length (0. )
169+ offset_upper_level : list [Length ] = []
170+ offset_table = Table ()
171+
172+ def set_offset (level : int , offset : Length ):
173+ nonlocal offset_upper_level
174+ offset_upper_level = offset_upper_level [:level ]
175+ if len (offset_upper_level ) < level :
176+ offset_upper_level += [0 ] * (level - len (offset_upper_level ))
177+
178+ offset_upper_level .append (offset )
179+
168180 for row in range (self .table .num_rows ):
169181 column = 1
170182 while column < self .table .num_columns :
171- if column + 2 < self .table .num_columns and self .table [row , column + 2 ] and self .table [row , column ]:
172- _original_length , trim_correction = self .parse_correction (self .table [row , column ])
173- original_length = Length (_original_length )
174- scaled_length = original_length * factor
175- if trim_correction is not None :
176- trim_correction *= factor
183+ if self .table [row , column ]:
184+
185+ if column + 2 < self .table .num_columns and self .table [row , column + 2 ]:
186+ # not a gallery line
187+ _original_length , trim_correction = self .parse_correction (self .table [row , column ])
188+ is_fixed_length = _original_length .endswith ("!" ) or (column == 1 and not scale_lower_floor )
189+ original_length = Length (_original_length .replace ("!" , "" ))
190+ scaled_length = original_length * factor
191+
192+ if trim_correction is not None and not trim_correction .endswith ("!" ):
193+ trim_correction = str (Length (trim_correction ) * factor )
194+ if not trim_correction .startswith ("-" ):
195+ trim_correction = "+" + trim_correction
196+
197+
198+ if is_fixed_length :
199+ # riser offset
200+ # riser_theoretical = riser_original * factor
201+ # factor < 1 => riser remains longer than it should -> next floor should be shorter to compensate
202+ target_length = original_length
203+ offset = scaled_length - original_length
204+ if column > 2 and offset_upper_level [column // 2 - 1 ]:
205+ offset += offset_upper_level [column // 2 - 1 ]
206+ set_offset (column // 2 , offset )
207+ else :
208+ target_length = scaled_length
209+ offset = offset_upper_level [column // 2 - 1 ]
210+ if offset :
211+ target_length += offset
212+
213+ offset_table [row , column ] = offset
214+
215+ set_offset (column // 2 , None )
216+
217+ cell_content = str (target_length )
218+ if is_fixed_length :
219+ cell_content += "!"
220+
221+ if trim_correction is not None :
222+ cell_content += trim_correction
223+
224+ self .table [row , column ] = cell_content
177225
178- if column == 1 and not scale_lower_floor :
179- # riser offset
180- # riser_theoretical = riser_original * factor
181- # factor < 1 => riser remains longer than it should -> next floor should be shorter to compensate
182- offset_2nd_level = scaled_length - original_length
183- else :
184- if column == 3 :
185- scaled_length += offset_2nd_level
186-
187- self .table [row , column ] = scaled_length
188-
189226 column += 2
190227
191228 return self
0 commit comments