@@ -46,8 +46,6 @@ TRCFileAdapter::extendRead(const std::string& fileName) const {
4646 FileDoesNotExist,
4747 fileName);
4848
49- auto table = std::make_shared<TimeSeriesTableVec3>();
50-
5149 // Callable to get the next line in form of vector of tokens.
5250 auto nextLine = [&] {
5351 return getNextLine (in_stream, _delimitersRead);
@@ -62,7 +60,8 @@ TRCFileAdapter::extendRead(const std::string& fileName) const {
6260 fileName);
6361 OPENSIM_THROW_IF (header_tokens.at (0 ) != " PathFileType" ,
6462 MissingHeader);
65- table->updTableMetaData ().setValueForKey (" header" , header);
63+ AbstractDataTable::TableMetaData metaData{};
64+ metaData.setValueForKey (" header" , header);
6665
6766 // Read the line containing metadata keys.
6867 auto keys = nextLine ();
@@ -94,11 +93,10 @@ TRCFileAdapter::extendRead(const std::string& fileName) const {
9493
9594 // Fill up the metadata container.
9695 for (std::size_t i = 0 ; i < keys.size (); ++i)
97- table-> updTableMetaData () .setValueForKey (keys[i], values[i]);
96+ metaData .setValueForKey (keys[i], values[i]);
9897
9998 auto num_markers_expected =
100- std::stoul (table->
101- getTableMetaData ().
99+ std::stoul (metaData.
102100 getValueForKey (_numMarkersLabel).
103101 template getValue<std::string>());
104102
@@ -169,9 +167,16 @@ TRCFileAdapter::extendRead(const std::string& fileName) const {
169167 }
170168
171169 const size_t expected{ column_labels.size () * 3 + 2 };
170+ // Will first store data in a SimTK::Matrix to avoid expensive calls
171+ // to the table's appendRow() which reallocates and copies the whole table.
172+ int rowNumber = 0 ;
173+ int last_size = 1024 ;
174+ SimTK::Matrix_<SimTK::Vec3> markerData{last_size, static_cast <int >(num_markers_expected)};
175+ std::vector<double > times;
176+ times.resize (last_size);
172177
173178 // An empty line during data parsing denotes end of data
174- while (!row.empty ()) {
179+ while (!row.empty ()) {
175180 OPENSIM_THROW_IF (row.size () != expected,
176181 RowLengthMismatch,
177182 fileName,
@@ -194,21 +199,32 @@ TRCFileAdapter::extendRead(const std::string& fileName) const {
194199 } // otherwise the value will remain NaN (default)
195200 ++ind;
196201 }
197-
202+ markerData[rowNumber] = row_vector;
198203 // Column 1 is time.
199- table->appendRow (std::stod (row.at (1 )), std::move (row_vector));
200-
204+ times[rowNumber] = std::stod (row.at (1 ));
205+ rowNumber++;
206+ if (rowNumber== last_size) {
207+ // resize all Data/Matrices, double the size while keeping data
208+ int newSize = last_size * 2 ;
209+ times.resize (newSize);
210+ // Repeat for Data matrices in use
211+ markerData.resizeKeep (newSize, num_markers_expected);
212+ last_size = newSize;
213+ }
201214 row = nextLine ();
202215 ++line_num;
203216 }
217+ // Trim Matrices in use to actual data and move into tables
218+ times.resize (rowNumber);
219+ markerData.resizeKeep (rowNumber, num_markers_expected);
204220
205221 // Set the column labels of the table.
206- ValueArray <std::string> value_array {};
222+ std::vector <std::string> labels {};
207223 for (const auto & cl : column_labels)
208- value_array. upd () .push_back (SimTK::Value<std::string>{cl});
209- TimeSeriesTableVec3::DependentsMetaData dep_metadata{};
210- dep_metadata. setValueArrayForKey ( " labels " , value_array );
211- table->setDependentsMetaData (dep_metadata) ;
224+ labels .push_back (SimTK::Value<std::string>{cl});
225+ auto table = std::make_shared<TimeSeriesTableVec3>(
226+ times, markerData, labels );
227+ table->updTableMetaData () = metaData ;
212228
213229 OutputTables output_tables{};
214230 output_tables.emplace (_markers, table);
0 commit comments