1 #include "FeaturesFile.h"
2 #include "FeaturesFile.h"
3 #include "ArchiveExtractor.h"
6 #include "../invalid_odb_error.h"
8 #include "../parse_error.h"
9 #include "SymbolName.h"
10 #include "equals_within.h"
14 namespace Odb::Lib::FileModel::Design
16 FeaturesFile::FeaturesFile()
25 FeaturesFile::~FeaturesFile()
27 m_featureRecords.clear();
28 m_attributeNames.clear();
29 m_attributeTextValues.clear();
30 m_symbolNamesByName.clear();
33 bool FeaturesFile::Parse(std::filesystem::path directory,
const std::string& alternateFilename )
35 std::ifstream featuresFile;
41 m_directory = directory;
43 loginfo(
"checking for extraction...");
45 std::vector<std::string> filenames;
46 if (alternateFilename.empty())
48 std::copy(std::begin(FEATURES_FILENAMES), std::end(FEATURES_FILENAMES), std::back_inserter(filenames));
52 filenames.push_back(alternateFilename);
55 std::filesystem::path featuresFilePath;
56 for (
const auto& featuresFilename : filenames)
58 loginfo(
"trying features file: [" + featuresFilename +
"]...");
60 featuresFilePath = Utils::ArchiveExtractor::getUncompressedFilePath(m_directory, featuresFilename);
61 if (exists(featuresFilePath) && is_regular_file(featuresFilePath))
63 loginfo(
"found features file: [" + featuresFilePath.string() +
"]");
68 m_path = featuresFilePath;
70 loginfo(
"any extraction complete, parsing data...");
72 if (!std::filesystem::exists(m_path))
74 auto message =
"features file does not exist: [" + m_path.string() +
"]";
75 throw invalid_odb_error(message.c_str());
77 else if (!std::filesystem::is_regular_file(m_path))
79 auto message =
"features is not a file: [" + m_path.string() +
"]";
80 throw invalid_odb_error(message.c_str());
83 featuresFile.open(m_path.string(), std::ios::in);
84 if (!featuresFile.is_open())
86 auto message =
"unable to open features file: [" + m_path.string() +
"]";
87 throw invalid_odb_error(message.c_str());
90 std::shared_ptr<FeatureRecord> pCurrentFeatureRecord;
91 std::shared_ptr<ContourPolygon> pCurrentContourPolygon;
93 while (std::getline(featuresFile, line))
98 Utils::str_trim(line);
101 std::stringstream lineStream(line);
104 if (line.find(COMMENT_TOKEN) == 0)
108 else if (line.find(UNITS_TOKEN) == 0)
112 if (!std::getline(lineStream, token,
'='))
114 throw_parse_error(m_path, line, token, lineNumber);
116 else if (!std::getline(lineStream, token,
'='))
118 throw_parse_error(m_path, line, token, lineNumber);
123 else if (line.find(
"U") == 0)
126 if (!std::getline(lineStream, token,
' '))
128 throw_parse_error(m_path, line, token, lineNumber);
130 else if (!std::getline(lineStream, token,
' '))
132 throw_parse_error(m_path, line, token, lineNumber);
137 else if (line.find(ID_TOKEN) == 0)
140 if (!std::getline(lineStream, token,
'='))
142 throw_parse_error(m_path, line, token, lineNumber);
144 else if (!std::getline(lineStream, token,
'='))
146 throw_parse_error(m_path, line, token, lineNumber);
148 m_id = std::stoul(token);
150 else if (line.find(NUM_FEATURES_TOKEN) == 0)
155 if (!(lineStream >> token))
157 throw_parse_error(m_path, line, token, lineNumber);
160 if (token != NUM_FEATURES_TOKEN)
162 throw_parse_error(m_path, line, token, lineNumber);
165 if (!(lineStream >> m_numFeatures))
167 throw_parse_error(m_path, line, token, lineNumber);
170 else if (line.find(ATTRIBUTE_NAME_TOKEN) == 0)
175 if (!std::getline(lineStream, token,
' '))
177 throw_parse_error(m_path, line, token, lineNumber);
179 else if (!std::getline(lineStream, token,
' '))
181 throw_parse_error(m_path, line, token, lineNumber);
183 m_attributeNames.push_back(token);
185 else if (line.find(ATTRIBUTE_VALUE_TOKEN) == 0)
189 if (!std::getline(lineStream, token,
' '))
191 throw_parse_error(m_path, line, token, lineNumber);
193 else if (!std::getline(lineStream, token,
' '))
195 throw_parse_error(m_path, line, token, lineNumber);
197 m_attributeTextValues.push_back(token);
199 else if (line.find(SYMBOL_NAME_TOKEN) == 0)
202 auto pSymbolName = std::make_shared<SymbolName>();
203 if (!pSymbolName->SymbolName::Parse(m_path, line, lineNumber))
205 throw_parse_error(m_path, line,
"", lineNumber);
207 m_symbolNamesByName[pSymbolName->GetName()] = pSymbolName;
209 else if (line.find(FeatureRecord::LINE_TOKEN) == 0)
212 if (!(lineStream >> token) || token != FeatureRecord::LINE_TOKEN)
214 throw_parse_error(m_path, line, token, lineNumber);
217 auto pFeatureRecord = std::make_shared<FeatureRecord>();
218 pFeatureRecord->type = FeatureRecord::Type::Line;
220 if (!(lineStream >> pFeatureRecord->xs))
222 throw_parse_error(m_path, line, token, lineNumber);
225 if (!(lineStream >> pFeatureRecord->ys))
227 throw_parse_error(m_path, line, token, lineNumber);
230 if (!(lineStream >> pFeatureRecord->xe))
232 throw_parse_error(m_path, line, token, lineNumber);
235 if (!(lineStream >> pFeatureRecord->ye))
237 throw_parse_error(m_path, line, token, lineNumber);
240 if (!(lineStream >> pFeatureRecord->sym_num))
242 throw_parse_error(m_path, line, token, lineNumber);
246 if (!(lineStream >> polarity))
248 throw_parse_error(m_path, line, token, lineNumber);
252 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
253 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
254 default: throw_parse_error(m_path, line, token, lineNumber);
257 if (!(lineStream >> pFeatureRecord->dcode))
259 throw_parse_error(m_path, line, token, lineNumber);
262 std::string attrIdString;
263 lineStream >> attrIdString;
265 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
267 throw_parse_error(m_path, line, token, lineNumber);
270 m_featureRecords.push_back(pFeatureRecord);
272 else if (line.find(FeatureRecord::PAD_TOKEN) == 0)
275 if (!(lineStream >> token) || token != FeatureRecord::PAD_TOKEN)
277 throw_parse_error(m_path, line, token, lineNumber);
280 auto pFeatureRecord = std::make_shared<FeatureRecord>();
281 pFeatureRecord->type = FeatureRecord::Type::Pad;
283 if (!(lineStream >> pFeatureRecord->x))
285 throw_parse_error(m_path, line, token, lineNumber);
288 if (!(lineStream >> pFeatureRecord->y))
290 throw_parse_error(m_path, line, token, lineNumber);
293 if (!(lineStream >> pFeatureRecord->apt_def_symbol_num))
295 throw_parse_error(m_path, line, token, lineNumber);
297 if (pFeatureRecord->apt_def_symbol_num == -1)
299 if (!(lineStream >> pFeatureRecord->apt_def_resize_factor))
301 throw_parse_error(m_path, line, token, lineNumber);
306 if (!(lineStream >> polarity))
308 throw_parse_error(m_path, line, token, lineNumber);
312 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
313 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
314 default: throw_parse_error(m_path, line, token, lineNumber);
317 if (!(lineStream >> pFeatureRecord->dcode))
319 throw_parse_error(m_path, line, token, lineNumber);
322 if (!(lineStream >> pFeatureRecord->orient_def))
324 throw_parse_error(m_path, line, token, lineNumber);
327 std::string attrIdString;
328 lineStream >> attrIdString;
330 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
332 throw_parse_error(m_path, line, token, lineNumber);
335 m_featureRecords.push_back(pFeatureRecord);
337 else if (line.find(FeatureRecord::TEXT_TOKEN) == 0)
340 if (!(lineStream >> token) || token != FeatureRecord::TEXT_TOKEN)
342 throw_parse_error(m_path, line, token, lineNumber);
345 auto pFeatureRecord = std::make_shared<FeatureRecord>();
346 pFeatureRecord->type = FeatureRecord::Type::Text;
348 if (!(lineStream >> pFeatureRecord->x))
350 throw_parse_error(m_path, line, token, lineNumber);
353 if (!(lineStream >> pFeatureRecord->y))
355 throw_parse_error(m_path, line, token, lineNumber);
358 if (!(lineStream >> pFeatureRecord->font))
360 throw_parse_error(m_path, line, token, lineNumber);
364 if (!(lineStream >> polarity))
366 throw_parse_error(m_path, line, token, lineNumber);
370 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
371 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
372 default: throw_parse_error(m_path, line, token, lineNumber);
375 if (!(lineStream >> pFeatureRecord->orient_def))
377 throw_parse_error(m_path, line, token, lineNumber);
380 if (pFeatureRecord->orient_def == 8 ||
381 pFeatureRecord->orient_def == 9)
383 if (!(lineStream >> pFeatureRecord->orient_def_rotation))
385 throw_parse_error(m_path, line, token, lineNumber);
389 if (!(lineStream >> pFeatureRecord->xsize))
391 throw_parse_error(m_path, line, token, lineNumber);
394 if (!(lineStream >> pFeatureRecord->ysize))
396 throw_parse_error(m_path, line, token, lineNumber);
399 if (!(lineStream >> pFeatureRecord->width_factor))
401 throw_parse_error(m_path, line, token, lineNumber);
404 if (!(lineStream >> std::quoted(pFeatureRecord->text,
'\'')))
406 throw_parse_error(m_path, line, token, lineNumber);
409 if (!(lineStream >> pFeatureRecord->version))
411 throw_parse_error(m_path, line, token, lineNumber);
414 std::string attrIdString;
415 lineStream >> attrIdString;
417 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
419 throw_parse_error(m_path, line, token, lineNumber);
422 m_featureRecords.push_back(pFeatureRecord);
424 else if (line.find(FeatureRecord::ARC_TOKEN) == 0)
427 if (!(lineStream >> token) || token != FeatureRecord::ARC_TOKEN)
429 throw_parse_error(m_path, line, token, lineNumber);
432 auto pFeatureRecord = std::make_shared<FeatureRecord>();
433 pFeatureRecord->type = FeatureRecord::Type::Arc;
435 if (!(lineStream >> pFeatureRecord->xs))
437 throw_parse_error(m_path, line, token, lineNumber);
440 if (!(lineStream >> pFeatureRecord->ys))
442 throw_parse_error(m_path, line, token, lineNumber);
445 if (!(lineStream >> pFeatureRecord->xe))
447 throw_parse_error(m_path, line, token, lineNumber);
450 if (!(lineStream >> pFeatureRecord->ye))
452 throw_parse_error(m_path, line, token, lineNumber);
455 if (!(lineStream >> pFeatureRecord->xc))
457 throw_parse_error(m_path, line, token, lineNumber);
460 if (!(lineStream >> pFeatureRecord->yc))
462 throw_parse_error(m_path, line, token, lineNumber);
466 if (!(lineStream >> pFeatureRecord->sym_num))
468 throw_parse_error(m_path, line, token, lineNumber);
472 if (!(lineStream >> polarity))
474 throw_parse_error(m_path, line, token, lineNumber);
478 case 'P': pFeatureRecord->polarity = Polarity::Positive;
break;
479 case 'N': pFeatureRecord->polarity = Polarity::Negative;
break;
480 default: throw_parse_error(m_path, line, token, lineNumber);
483 if (!(lineStream >> pFeatureRecord->dcode))
485 throw_parse_error(m_path, line, token, lineNumber);
489 if (!(lineStream >> cw))
491 throw_parse_error(m_path, line, token, lineNumber);
495 case 'Y': pFeatureRecord->cw =
true;
break;
496 case 'N': pFeatureRecord->cw =
false;
break;
497 default: throw_parse_error(m_path, line, token, lineNumber);
500 std::string attrIdString;
501 lineStream >> attrIdString;
503 if (!pFeatureRecord->ParseAttributeLookupTable(attrIdString))
505 throw_parse_error(m_path, line, token, lineNumber);
508 m_featureRecords.push_back(pFeatureRecord);
510 else if (line.find(FeatureRecord::BARCODE_TOKEN) == 0)
513 if (!(lineStream >> token) || token != FeatureRecord::BARCODE_TOKEN)
515 throw_parse_error(m_path, line, token, lineNumber);
518 auto pFeatureRecord = std::make_shared<FeatureRecord>();
519 pFeatureRecord->type = FeatureRecord::Type::Barcode;
531 m_featureRecords.push_back(pFeatureRecord);
533 else if (line.find(FeatureRecord::SURFACE_START_TOKEN) == 0 &&
534 line.size() > 1 && line[1] ==
' ')
537 if (!(lineStream >> token) || token != FeatureRecord::SURFACE_START_TOKEN)
539 throw_parse_error(m_path, line, token, lineNumber);
542 pCurrentFeatureRecord = std::make_shared<FeatureRecord>();
543 pCurrentFeatureRecord->type = FeatureRecord::Type::Surface;
546 if (!(lineStream >> polarity))
548 throw_parse_error(m_path, line, token, lineNumber);
552 case 'P': pCurrentFeatureRecord->polarity = Polarity::Positive;
break;
553 case 'N': pCurrentFeatureRecord->polarity = Polarity::Negative;
break;
554 default: throw_parse_error(m_path, line, token, lineNumber);
557 if (!(lineStream >> pCurrentFeatureRecord->dcode))
559 throw_parse_error(m_path, line, token, lineNumber);
562 std::string attrIdString;
563 lineStream >> attrIdString;
565 if (!pCurrentFeatureRecord->ParseAttributeLookupTable(attrIdString))
567 throw_parse_error(m_path, line, token, lineNumber);
570 else if (line.find(FeatureRecord::SURFACE_END_TOKEN) == 0)
573 if (!(lineStream >> token) || token != FeatureRecord::SURFACE_END_TOKEN)
575 throw_parse_error(m_path, line, token, lineNumber);
578 if (pCurrentFeatureRecord !=
nullptr)
580 m_featureRecords.push_back(pCurrentFeatureRecord);
581 pCurrentFeatureRecord.reset();
585 throw_parse_error(m_path, line, token, lineNumber);
588 else if (line.find(ContourPolygon::BEGIN_RECORD_TOKEN) == 0)
591 if (!(lineStream >> token))
593 throw_parse_error(m_path, line, token, lineNumber);
596 if (token != ContourPolygon::BEGIN_RECORD_TOKEN)
598 throw_parse_error(m_path, line, token, lineNumber);
601 pCurrentContourPolygon = std::make_shared<ContourPolygon>();
603 if (!(lineStream >> pCurrentContourPolygon->xStart))
605 throw_parse_error(m_path, line, token, lineNumber);
608 if (!(lineStream >> pCurrentContourPolygon->yStart))
610 throw_parse_error(m_path, line, token, lineNumber);
613 if (!(lineStream >> token))
615 throw_parse_error(m_path, line, token, lineNumber);
618 if (token == ContourPolygon::ISLAND_TYPE_TOKEN)
620 pCurrentContourPolygon->type = ContourPolygon::Type::Island;
622 else if (token == ContourPolygon::HOLE_TYPE_TOKEN)
624 pCurrentContourPolygon->type = ContourPolygon::Type::Hole;
628 throw_parse_error(m_path, line, token, lineNumber);
631 else if (line.find(ContourPolygon::END_RECORD_TOKEN) == 0)
634 if (!(lineStream >> token))
636 throw_parse_error(m_path, line, token, lineNumber);
639 if (token != ContourPolygon::END_RECORD_TOKEN)
641 throw_parse_error(m_path, line, token, lineNumber);
644 if (pCurrentFeatureRecord !=
nullptr)
646 pCurrentFeatureRecord->m_contourPolygons.push_back(pCurrentContourPolygon);
647 pCurrentContourPolygon.reset();
651 throw_parse_error(m_path, line, token, lineNumber);
654 else if (line.find(ContourPolygon::PolygonPart::ARC_RECORD_TOKEN) == 0)
657 if (!(lineStream >> token))
659 throw_parse_error(m_path, line, token, lineNumber);
662 if (token != ContourPolygon::PolygonPart::ARC_RECORD_TOKEN)
664 throw_parse_error(m_path, line, token, lineNumber);
667 auto pPolygonPart = std::make_shared<ContourPolygon::PolygonPart>();
668 pPolygonPart->type = ContourPolygon::PolygonPart::Type::Arc;
670 if (!(lineStream >> pPolygonPart->endX))
672 throw_parse_error(m_path, line, token, lineNumber);
675 if (!(lineStream >> pPolygonPart->endY))
677 throw_parse_error(m_path, line, token, lineNumber);
680 if (!(lineStream >> pPolygonPart->xCenter))
682 throw_parse_error(m_path, line, token, lineNumber);
685 if (!(lineStream >> pPolygonPart->yCenter))
687 throw_parse_error(m_path, line, token, lineNumber);
690 if (!(lineStream >> token))
692 throw_parse_error(m_path, line, token, lineNumber);
695 if (token ==
"y" || token ==
"Y")
697 pPolygonPart->isClockwise =
true;
699 else if (token ==
"n" || token ==
"N")
701 pPolygonPart->isClockwise =
false;
705 throw_parse_error(m_path, line, token, lineNumber);
708 if (pCurrentContourPolygon !=
nullptr)
710 pCurrentContourPolygon->m_polygonParts.push_back(pPolygonPart);
714 throw_parse_error(m_path, line, token, lineNumber);
717 else if (line.find(ContourPolygon::PolygonPart::SEGMENT_RECORD_TOKEN) == 0)
720 if (!(lineStream >> token))
722 throw_parse_error(m_path, line, token, lineNumber);
725 if (token != ContourPolygon::PolygonPart::SEGMENT_RECORD_TOKEN)
727 throw_parse_error(m_path, line, token, lineNumber);
730 auto pPolygonPart = std::make_shared<ContourPolygon::PolygonPart>();
731 pPolygonPart->type = ContourPolygon::PolygonPart::Type::Segment;
733 if (!(lineStream >> pPolygonPart->endX))
735 throw_parse_error(m_path, line, token, lineNumber);
738 if (!(lineStream >> pPolygonPart->endY))
740 throw_parse_error(m_path, line, token, lineNumber);
743 if (pCurrentContourPolygon !=
nullptr)
745 pCurrentContourPolygon->m_polygonParts.push_back(pPolygonPart);
749 throw_parse_error(m_path, line, token, lineNumber);
755 parse_info pi(m_path, line, lineNumber);
756 logwarn(pi.toString(
"unrecognized record line in features file:"));
762 if (pCurrentFeatureRecord !=
nullptr)
765 m_featureRecords.push_back(pCurrentFeatureRecord);
766 pCurrentFeatureRecord.reset();
769 featuresFile.close();
771 catch (parse_error& pe)
773 auto m = pe.toString(
"Parse Error:");
775 featuresFile.close();
778 catch (std::exception& e)
780 parse_info pi(m_path, line, lineNumber);
781 const auto m = pi.toString();
782 logexception_msg(e, m);
783 featuresFile.close();
790 std::string FeaturesFile::GetUnits()
const
795 std::filesystem::path FeaturesFile::GetPath()
800 std::filesystem::path FeaturesFile::GetDirectory()
805 int FeaturesFile::GetNumFeatures()
const
807 return m_numFeatures;
810 unsigned int FeaturesFile::GetId()
const
815 const SymbolName::StringMap& FeaturesFile::GetSymbolNamesByName()
const
817 return m_symbolNamesByName;
820 const FeaturesFile::FeatureRecord::Vector& FeaturesFile::GetFeatureRecords()
const
822 return m_featureRecords;
825 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile> FeaturesFile::to_protobuf()
const
827 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile> pFeaturesFileMessage(
new Odb::Lib::Protobuf::FeaturesFile);
828 pFeaturesFileMessage->set_id(m_id);
829 pFeaturesFileMessage->set_numfeatures(m_numFeatures);
830 pFeaturesFileMessage->set_units(m_units);
831 for (
const auto& pFeatureRecord : m_featureRecords)
833 pFeaturesFileMessage->add_featurerecords()->CopyFrom(*pFeatureRecord->to_protobuf());
835 for (
const auto& kvSymbolName : m_symbolNamesByName)
837 (*pFeaturesFileMessage->mutable_symbolnamesbyname())[kvSymbolName.first] = *kvSymbolName.second->to_protobuf();
839 return pFeaturesFileMessage;
842 void FeaturesFile::from_protobuf(
const Odb::Lib::Protobuf::FeaturesFile& message)
845 m_numFeatures = message.numfeatures();
846 m_units = message.units();
847 for (
const auto& featureRecordMessage : message.featurerecords())
849 std::shared_ptr<FeatureRecord> pFeatureRecord(
new FeatureRecord);
850 pFeatureRecord->from_protobuf(featureRecordMessage);
851 m_featureRecords.push_back(pFeatureRecord);
853 for (
const auto& kvSymbolNameMessage : message.symbolnamesbyname())
855 auto pSymbolName = std::make_shared<SymbolName>();
856 pSymbolName->from_protobuf(kvSymbolNameMessage.second);
857 m_symbolNamesByName[kvSymbolNameMessage.first] = pSymbolName;
861 FeaturesFile::FeatureRecord::~FeatureRecord()
863 m_contourPolygons.clear();
866 const ContourPolygon::Vector& FeaturesFile::FeatureRecord::GetContourPolygons()
const
868 return m_contourPolygons;
871 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord> Odb::Lib::FileModel::Design::FeaturesFile::FeatureRecord::to_protobuf()
const
873 std::unique_ptr<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord> pFeatureRecordMessage(
new Odb::Lib::Protobuf::FeaturesFile::FeatureRecord);
874 pFeatureRecordMessage->set_apt_def_resize_factor(apt_def_resize_factor);
875 pFeatureRecordMessage->set_xc(xc);
876 pFeatureRecordMessage->set_yc(yc);
877 pFeatureRecordMessage->set_cw(cw);
878 pFeatureRecordMessage->set_font(font);
879 pFeatureRecordMessage->set_xsize(xsize);
880 pFeatureRecordMessage->set_ysize(ysize);
881 pFeatureRecordMessage->set_width_factor(width_factor);
882 pFeatureRecordMessage->set_text(text);
883 pFeatureRecordMessage->set_version(version);
884 pFeatureRecordMessage->set_sym_num(sym_num);
885 pFeatureRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
886 pFeatureRecordMessage->set_dcode(dcode);
887 pFeatureRecordMessage->set_id(
id);
888 pFeatureRecordMessage->set_orient_def(orient_def);
889 pFeatureRecordMessage->set_orient_def_rotation(orient_def_rotation);
890 pFeatureRecordMessage->set_type(
static_cast<Odb::Lib::Protobuf::FeaturesFile::FeatureRecord::Type
>(type));
891 pFeatureRecordMessage->set_xs(xs);
892 pFeatureRecordMessage->set_ys(ys);
893 pFeatureRecordMessage->set_xe(xe);
894 pFeatureRecordMessage->set_ye(ye);
895 pFeatureRecordMessage->set_x(x);
896 pFeatureRecordMessage->set_y(y);
897 pFeatureRecordMessage->set_apt_def_symbol_num(apt_def_symbol_num);
898 for (
const auto& pContourPolygon : m_contourPolygons)
900 pFeatureRecordMessage->add_contourpolygons()->CopyFrom(*pContourPolygon->to_protobuf());
902 for (
const auto& kvAttributeAssignment : m_attributeLookupTable)
904 (*pFeatureRecordMessage->mutable_attributelookuptable())[kvAttributeAssignment.first] = kvAttributeAssignment.second;
906 return pFeatureRecordMessage;
909 void Odb::Lib::FileModel::Design::FeaturesFile::FeatureRecord::from_protobuf(
const Odb::Lib::Protobuf::FeaturesFile::FeatureRecord& message)
911 apt_def_resize_factor = message.apt_def_resize_factor();
915 font = message.font();
916 xsize = message.xsize();
917 ysize = message.ysize();
918 width_factor = message.width_factor();
919 text = message.text();
920 version = message.version();
921 sym_num = message.sym_num();
922 polarity =
static_cast<Polarity
>(message.polarity());
923 dcode = message.dcode();
925 orient_def = message.orient_def();
926 orient_def_rotation = message.orient_def_rotation();
927 type =
static_cast<Type
>(message.type());
934 apt_def_symbol_num = message.apt_def_symbol_num();
935 for (
const auto& contourPolygonMessage : message.contourpolygons())
937 std::shared_ptr<ContourPolygon> pContourPolygon(
new ContourPolygon);
938 pContourPolygon->from_protobuf(contourPolygonMessage);
939 m_contourPolygons.push_back(pContourPolygon);
941 for (
const auto& kvAttributeAssignment : message.attributelookuptable())
943 m_attributeLookupTable[kvAttributeAssignment.first] = kvAttributeAssignment.second;